Skip to content

Commit ff63a04

Browse files
chore: add ruff to lint and format python code
1 parent 21525de commit ff63a04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+560
-379
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,7 @@ coverage
3232
.ionide
3333

3434
# IntelliJ
35-
.idea
35+
.idea
36+
37+
# Ruff
38+
.ruff_cache

.husky/pre-commit

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
echo "Running static tests..."
2+
pnpm run test:static
3+
echo "Done running static tests."
4+
5+
echo "Formatting code..."
6+
pnpm run format
7+
echo "Done formatting code."

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# django-react-typescript <!-- omit from toc -->
22

3-
<img alt="django-react-typescript logo" src="assets/Logo.png" align="right" width="95" height="95" />
3+
<img alt="django-react-typescript logo" src="assets/Logo.png" align="right" width="120" height="120" />
44

55
This is an non-opinionated Django 5 + React 18 boilerplate built with great development experience and easy deployment in mind.
66

api/apps.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33

44
class ApiConfig(AppConfig):
5-
name = 'api'
5+
name = "api"

api/filters/publications.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from django_filters import rest_framework as filters
22
from backend.models.publications import Publication
33

4+
45
class PublicationFilter(filters.FilterSet):
5-
tag = filters.CharFilter(field_name='tag', lookup_expr='icontains')
6-
title = filters.CharFilter(field_name='title', lookup_expr='icontains')
6+
tag = filters.CharFilter(field_name="tag", lookup_expr="icontains")
7+
title = filters.CharFilter(field_name="title", lookup_expr="icontains")
78

89
class Meta:
910
model = Publication
10-
fields = ['title', 'tag']
11+
fields = ["title", "tag"]

api/serializers/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
from .publications import PublicationsSerializer
2-
from .subscribers import SubscribersSerializer

api/serializers/publications.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
from rest_framework import serializers
22
from backend.models.publications import Publication
33

4+
45
class PublicationsSerializer(serializers.ModelSerializer):
56
image = serializers.SerializerMethodField(read_only=True)
67

78
def get_image(self, instance):
89
return instance.image.url
910

1011
class Meta:
11-
model = Publication
12-
fields = ('title', 'slug', 'description', 'body', 'image', 'tag', 'image_description', 'created_at')
12+
model = Publication
13+
fields = (
14+
"title",
15+
"slug",
16+
"description",
17+
"body",
18+
"image",
19+
"tag",
20+
"image_description",
21+
"created_at",
22+
)

api/serializers/subscribers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from rest_framework import serializers
22
from backend.models.subscribers import Subscriber
33

4+
45
class SubscribersSerializer(serializers.ModelSerializer):
56
class Meta:
67
model = Subscriber
7-
fields = ('name', 'contact_method', 'contact_info')
8+
fields = ("name", "contact_method", "contact_info")

api/tests.py

-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
from django.test import TestCase
2-
3-
# Create your tests here.

api/urls.py

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
from django.urls import re_path
22
from rest_framework.authtoken.views import obtain_auth_token
33
from .views.subscribers import SubscribersEndpoint
4-
from .views.publications import PublicationsEndpoint, PublicationsQueryEndpoint, PaginatedPublicationsQueryEndpoint, PaginatedPublicationsEndpoint, PublicationEndpoint
4+
from .views.publications import (
5+
PublicationsEndpoint,
6+
PublicationsQueryEndpoint,
7+
PaginatedPublicationsQueryEndpoint,
8+
PaginatedPublicationsEndpoint,
9+
PublicationEndpoint,
10+
)
511

612

713
urlpatterns = [
8-
re_path(r'^subscribers/$', SubscribersEndpoint.as_view() ),
9-
re_path(r'^publications/p/$', PaginatedPublicationsEndpoint.as_view() ),
10-
re_path(r'^publications/filter/$', PublicationsQueryEndpoint.as_view() ),
11-
re_path(r'^publications/p/filter/$', PaginatedPublicationsQueryEndpoint.as_view()),
12-
re_path(r'^publications/(?P<slug>[\w\-]+)/$', PublicationEndpoint.as_view()),
13-
re_path(r'^publications/$', PublicationsEndpoint.as_view() ),
14-
re_path(r'^authenticate/$', obtain_auth_token)
15-
]
14+
re_path(r"^subscribers/$", SubscribersEndpoint.as_view()),
15+
re_path(r"^publications/p/$", PaginatedPublicationsEndpoint.as_view()),
16+
re_path(r"^publications/filter/$", PublicationsQueryEndpoint.as_view()),
17+
re_path(r"^publications/p/filter/$", PaginatedPublicationsQueryEndpoint.as_view()),
18+
re_path(r"^publications/(?P<slug>[\w\-]+)/$", PublicationEndpoint.as_view()),
19+
re_path(r"^publications/$", PublicationsEndpoint.as_view()),
20+
re_path(r"^authenticate/$", obtain_auth_token),
21+
]

api/utils.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@
22
from rest_framework.response import Response
33
from collections import OrderedDict
44

5+
56
class Pagination(PageNumberPagination):
67
page_size = 9
7-
page_size_query_params = 'page_size'
8+
page_size_query_params = "page_size"
89
max_page_size = 100
910

1011
def get_paginated_response(self, data):
11-
return Response(OrderedDict([
12-
('count', self.page.paginator.count),
13-
('current_page', self.page.number),
14-
('total_pages', self.page.paginator.num_pages),
15-
('next', self.get_next_link()),
16-
('previous', self.get_previous_link()),
17-
('results', data)
18-
]))
12+
return Response(
13+
OrderedDict(
14+
[
15+
("count", self.page.paginator.count),
16+
("current_page", self.page.number),
17+
("total_pages", self.page.paginator.num_pages),
18+
("next", self.get_next_link()),
19+
("previous", self.get_previous_link()),
20+
("results", data),
21+
]
22+
)
23+
)

api/views/publications.py

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
1-
from rest_framework import generics, filters
1+
from rest_framework import generics
22
from rest_framework.views import APIView
33
from rest_framework.response import Response
44
from django_filters.rest_framework import DjangoFilterBackend
55
from backend.models.publications import Publication
66
from api.filters.publications import PublicationFilter
77
from api.serializers.publications import PublicationsSerializer
88
from api.utils import Pagination
9-
from rest_framework.permissions import IsAuthenticated
9+
from rest_framework.permissions import IsAuthenticated
10+
1011

1112
class PaginatedPublicationsEndpoint(generics.ListAPIView):
1213
permission_classes = (IsAuthenticated,)
1314
queryset = Publication.objects.all()
1415
serializer_class = PublicationsSerializer
1516
pagination_class = Pagination
1617

18+
1719
class PublicationsEndpoint(generics.ListAPIView):
1820
permission_classes = (IsAuthenticated,)
1921
queryset = Publication.objects.all()
2022
serializer_class = PublicationsSerializer
2123

24+
2225
class PublicationsQueryEndpoint(generics.ListAPIView):
2326
permission_classes = (IsAuthenticated,)
2427
queryset = Publication.objects.all()
2528
serializer_class = PublicationsSerializer
2629
filter_backends = [DjangoFilterBackend]
2730
filterset_class = PublicationFilter
2831

32+
2933
class PaginatedPublicationsQueryEndpoint(generics.ListAPIView):
3034
permission_classes = (IsAuthenticated,)
3135
queryset = Publication.objects.all()
@@ -34,27 +38,27 @@ class PaginatedPublicationsQueryEndpoint(generics.ListAPIView):
3438
filterset_class = PublicationFilter
3539
pagination_class = Pagination
3640

41+
3742
class PublicationEndpoint(APIView):
3843
permission_classes = (IsAuthenticated,)
3944

40-
4145
def get(self, request, format=None, **kwargs):
4246
"""
4347
Returns the a publication by its slug.
4448
"""
4549

4650
try:
47-
publication = Publication.objects.get(slug=kwargs.get('slug'))
51+
publication = Publication.objects.get(slug=kwargs.get("slug"))
4852

4953
formatted_publication = {
50-
'title': publication.title,
51-
'description': publication.description,
52-
'created_at': publication.created_at,
53-
'slug': publication.slug,
54-
'body': publication.body,
55-
'image': publication.image.url,
54+
"title": publication.title,
55+
"description": publication.description,
56+
"created_at": publication.created_at,
57+
"slug": publication.slug,
58+
"body": publication.body,
59+
"image": publication.image.url,
5660
}
57-
61+
5862
return Response(formatted_publication)
5963
except Publication.DoesNotExist:
60-
return Response("This publication doesn't exist yet.")
64+
return Response("This publication doesn't exist yet.")

api/views/subscribers.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
from backend.models.subscribers import Subscriber
21
from api.serializers.subscribers import SubscribersSerializer
32
from rest_framework.views import APIView
43
from rest_framework.response import Response
54
from rest_framework import status
6-
from rest_framework.permissions import IsAuthenticated
5+
from rest_framework.permissions import IsAuthenticated
6+
77

88
class SubscribersEndpoint(APIView):
99
"""
1010
Interface for users to send their subscription data.
1111
"""
12+
1213
permission_classes = (IsAuthenticated,)
1314

14-
def post(self,request):
15+
def post(self, request):
1516
serializer = SubscribersSerializer(data=request.data)
16-
17+
1718
if serializer.is_valid():
1819
serializer.save()
1920
return Response(status=status.HTTP_201_CREATED)
20-
21-
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
2221

22+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

backend/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
default_app_config = 'backend.apps.BackendConfig'
1+
default_app_config = "backend.apps.BackendConfig"

backend/actions.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33

44

55
class ExportCsvMixin:
6-
def export_as_csv(self, request, queryset):
6+
def export_as_csv(self, _, queryset):
77
meta = self.model._meta
88
field_names = [field.name for field in meta.fields]
99

10-
response = HttpResponse(content_type='text/csv')
11-
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
10+
response = HttpResponse(content_type="text/csv")
11+
response["Content-Disposition"] = "attachment; filename={}.csv".format(meta)
1212
writer = csv.writer(response)
1313

1414
writer.writerow(field_names)
1515
for obj in queryset:
16-
row = writer.writerow([getattr(obj, field) for field in field_names])
16+
writer.writerow([getattr(obj, field) for field in field_names])
1717

1818
return response
1919

20-
export_as_csv.short_description = "Export selected to CSV"
20+
export_as_csv.short_description = "Export selected to CSV"

backend/admin/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
from .publications import PublicationAdmin
2-
from .subscribers import SubscriberAdmin

backend/admin/publications.py

+16-15
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,29 @@
22
from django.utils.html import format_html
33
from django_better_admin_arrayfield.admin.mixins import DynamicArrayMixin
44
from backend.models.publications import Publication
5-
from backend.actions import ExportCsvMixin
65
from backend.utils import Strings
76

7+
88
@admin.register(Publication)
99
class PublicationAdmin(admin.ModelAdmin, DynamicArrayMixin):
1010
def image_preview(self, obj):
11-
return format_html('<img src="{}" style="height: 150px" />'.format(obj.image.url))
12-
13-
image_preview.short_description = Strings.IMAGE
11+
return format_html(
12+
'<img src="{}" style="height: 150px" />'.format(obj.image.url)
13+
)
1414

15-
list_filter = ('created_at',)
16-
list_display = ('title', 'image_preview', 'created_at')
17-
readonly_fields = ['slug']
15+
image_preview.short_description = Strings.IMAGE
1816

17+
list_filter = ("created_at",)
18+
list_display = ("title", "image_preview", "created_at")
19+
readonly_fields = ["slug"]
1920

2021
fieldsets = (
21-
(None, {
22-
'fields': ('title', 'slug', 'body', 'image', 'tag')
23-
}),
24-
(Strings.OPTIONAL_FIELDS, {
25-
'classes': ('collapse',),
26-
'fields': ('description', 'image_description'),
27-
}),
22+
(None, {"fields": ("title", "slug", "body", "image", "tag")}),
23+
(
24+
Strings.OPTIONAL_FIELDS,
25+
{
26+
"classes": ("collapse",),
27+
"fields": ("description", "image_description"),
28+
},
29+
),
2830
)
29-

backend/admin/subscribers.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
@admin.register(Subscriber)
77
class SubscriberAdmin(admin.ModelAdmin, ExportCsvMixin):
8-
list_filter = ('contact_method', 'created_at')
8+
list_filter = ("contact_method", "created_at")
99
actions = ["export_as_csv"]
10-
search_fields = ['name']
11-
list_display = ('name', 'contact_info', 'created_at')
12-
readonly_fields = ['name', 'contact_info', 'contact_method']
10+
search_fields = ["name"]
11+
list_display = ("name", "contact_info", "created_at")
12+
readonly_fields = ["name", "contact_info", "contact_method"]
1313

1414
class Media:
15-
js = ('backend/subscribers.js',)
15+
js = ("backend/subscribers.js",)

backend/apps.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33

44
class BackendConfig(AppConfig):
5-
name = 'backend'
6-
verbose_name = 'Public website'
5+
name = "backend"
6+
verbose_name = "Public website"
77

88
def ready(self):
9-
import backend.signals
9+
return
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from django.core.management.base import BaseCommand
22
from django.core.cache import cache
33

4+
45
class Command(BaseCommand):
56
def handle(self, *args, **kwargs):
67
cache.clear()
7-
self.stdout.write('Cleared cache\n')
8+
self.stdout.write("Cleared cache\n")

0 commit comments

Comments
 (0)