From 6352deda3c4cc1ef6a1971f0e51edf1a011be04c Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 17 Apr 2021 14:57:38 +0300 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=D0=9F=D0=BE=D0=B4=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=BA=D0=B0=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D0=BD=D0=B0=20=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D0=BD=D0=B5=20Django?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/backend/settings.py | 17 +++++++---------- backend/requirements.txt | 1 + 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/backend/backend/settings.py b/backend/backend/settings.py index 54f089b..56e9dba 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -27,8 +27,8 @@ SECRET_KEY = "django-insecure-toz+*lt(ejm!l*)92w2ciqoh^1kz#a(abbpcn54-dbw(nxoy&7 DEBUG = True ALLOWED_HOSTS = [] -if DEBUG: - ALLOWED_HOSTS = ["0.0.0.0"] +if DEBUG: + ALLOWED_HOSTS = ["0.0.0.0", "localhost", "127.0.0.1"] # Application definition @@ -45,13 +45,7 @@ INSTALLED_APPS = [ ] SWAGGER_SETTINGS = { - 'SECURITY_DEFINITIONS': { - 'Bearer': { - 'type': 'apiKey', - 'name': 'Authorization', - 'in': 'header' - } - } + "SECURITY_DEFINITIONS": {"Bearer": {"type": "apiKey", "name": "Authorization", "in": "header"}} } MIDDLEWARE = [ @@ -130,7 +124,10 @@ SIMPLE_JWT = { } REST_FRAMEWORK = { - "DEFAULT_AUTHENTICATION_CLASSES": ("rest_framework_simplejwt.authentication.JWTAuthentication",) + "DEFAULT_AUTHENTICATION_CLASSES": ( + "rest_framework_simplejwt.authentication.JWTAuthentication", + ), + "DEFAULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"], } diff --git a/backend/requirements.txt b/backend/requirements.txt index 733426f..2c9488b 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,4 +1,5 @@ djangorestframework==3.12.4 +django-filter==2.4.0 markdown==3.3.4 appdirs==1.4.4 asgiref==3.3.4 From 64607efaf36594b28308db4e6fb6b9d57195fc07 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 17 Apr 2021 14:58:49 +0300 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=D0=9D=D0=BE=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C=20=D0=B2=20=D0=B0=D0=B4?= =?UTF-8?q?=D0=BC=D0=B8=D0=BD=D0=BA=D0=B5=20=D0=B8=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8F=20finished?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/backend/admin.py | 9 ++++++++- .../migrations/0002_todoitem_finished.py | 18 ++++++++++++++++++ backend/backend/models.py | 5 +++-- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 backend/backend/migrations/0002_todoitem_finished.py diff --git a/backend/backend/admin.py b/backend/backend/admin.py index 30e3873..e409db7 100644 --- a/backend/backend/admin.py +++ b/backend/backend/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from .models import ToDoList +from .models import ToDoList, ToDoItem class ToDoListAdmin(admin.ModelAdmin): @@ -9,4 +9,11 @@ class ToDoListAdmin(admin.ModelAdmin): list_editable = ["title"] +class ToDoItemAdmin(admin.ModelAdmin): + model = ToDoItem + list_display = ["parent", "finished", "text", "created_at"] + list_editable = ["finished", "text"] + + admin.site.register(ToDoList, ToDoListAdmin) +admin.site.register(ToDoItem, ToDoItemAdmin) diff --git a/backend/backend/migrations/0002_todoitem_finished.py b/backend/backend/migrations/0002_todoitem_finished.py new file mode 100644 index 0000000..2b47d01 --- /dev/null +++ b/backend/backend/migrations/0002_todoitem_finished.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2 on 2021-04-17 11:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("backend", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="todoitem", + name="finished", + field=models.BooleanField(default=False), + ), + ] diff --git a/backend/backend/models.py b/backend/backend/models.py index 1213ca4..8770082 100644 --- a/backend/backend/models.py +++ b/backend/backend/models.py @@ -5,10 +5,11 @@ from django.contrib.auth.models import User class ToDoList(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, default=None) title = models.CharField(max_length=250) - created_at = models.DateTimeField(auto_now_add=True) + created_at = models.DateTimeField(auto_now_add=True, db_index=True) class ToDoItem(models.Model): parent = models.ForeignKey(ToDoList, on_delete=models.CASCADE, null=False, default=None) text = models.TextField() - created_at = models.DateTimeField(auto_now_add=True) + finished = models.BooleanField(default=False, null=False, db_index=True) + created_at = models.DateTimeField(auto_now_add=True, db_index=True) From 8a2691065159887ab5554eb9d1aeb8c5f11c8ef4 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 17 Apr 2021 14:59:08 +0300 Subject: [PATCH 3/5] =?UTF-8?q?db:=20=D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA=D1=81=D0=BE=D0=B2=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B2=D0=B0=D0=B6=D0=BD=D1=8B=D1=85=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0003_auto_20210417_1157.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 backend/backend/migrations/0003_auto_20210417_1157.py diff --git a/backend/backend/migrations/0003_auto_20210417_1157.py b/backend/backend/migrations/0003_auto_20210417_1157.py new file mode 100644 index 0000000..1ddd3fc --- /dev/null +++ b/backend/backend/migrations/0003_auto_20210417_1157.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2 on 2021-04-17 11:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("backend", "0002_todoitem_finished"), + ] + + operations = [ + migrations.AlterField( + model_name="todoitem", + name="created_at", + field=models.DateTimeField(auto_now_add=True, db_index=True), + ), + migrations.AlterField( + model_name="todoitem", + name="finished", + field=models.BooleanField(db_index=True, default=False), + ), + migrations.AlterField( + model_name="todolist", + name="created_at", + field=models.DateTimeField(auto_now_add=True, db_index=True), + ), + ] From 0f2f291c18f888b9dfc0ff636480a606a3115fc6 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 17 Apr 2021 14:59:26 +0300 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=B0=D0=B3=D0=B8=D0=BD=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/backend/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/backend/settings.py b/backend/backend/settings.py index 56e9dba..32b39d6 100644 --- a/backend/backend/settings.py +++ b/backend/backend/settings.py @@ -128,6 +128,8 @@ REST_FRAMEWORK = { "rest_framework_simplejwt.authentication.JWTAuthentication", ), "DEFAULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"], + "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", + "PAGE_SIZE": 100, } From 3f5083f8e4a66c5905f64308d8f429639c3683e1 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 17 Apr 2021 15:00:04 +0300 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20=D0=B1=D0=B0=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE=D0=B5=20=D0=BF=D1=80=D0=BE=D1=81=D1=82=D0=BE=D0=B5?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Минимальное, но самодостаточное --- backend/backend/api.py | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/backend/backend/api.py b/backend/backend/api.py index 3239ffc..70a43fe 100644 --- a/backend/backend/api.py +++ b/backend/backend/api.py @@ -1,20 +1,50 @@ from rest_framework import viewsets, serializers, permissions from rest_framework import routers +from django_filters.rest_framework import DjangoFilterBackend -from .models import ToDoList +from .models import ToDoList, ToDoItem + + +class ToDoItemSerializer(serializers.HyperlinkedModelSerializer): + parent = serializers.PrimaryKeyRelatedField(many=False, read_only=True) + + class Meta: + model = ToDoItem + fields = ["id", "text", "finished", "created_at", "parent"] + + +class ToDoItemViewSet(viewsets.ModelViewSet): + serializer_class = ToDoItemSerializer + permission_classes = [permissions.IsAuthenticated] + filter_backends = [DjangoFilterBackend] + filterset_fields = ["parent", "finished"] + + def get_queryset(self): + user = self.request.user + if not user.is_authenticated: + # ветка только для генерации схемы + return ToDoItem.objects.all() + return ToDoItem.objects.filter(parent__user=user) class ToDoListSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = ToDoList - fields = ["title", "created_at"] + fields = ["id", "title", "created_at"] class ToDoListViewSet(viewsets.ModelViewSet): - queryset = ToDoList.objects.all() serializer_class = ToDoListSerializer permission_classes = [permissions.IsAuthenticated] + def get_queryset(self): + user = self.request.user + if not user.is_authenticated: + # ветка только для генерации схемы + return ToDoList.objects.all() + return ToDoList.objects.filter(user=user) + router = routers.DefaultRouter() -router.register(r"lists", ToDoListViewSet) +router.register(r"lists", ToDoListViewSet, basename="ToDoLists") +router.register(r"todo_items", ToDoItemViewSet, basename="ToDoItems")