feat: Добавлена базовая версия Django бекенда
1. Админка работает и кастомизируется 2. JWT работает 3. Добавлена миграция с первыми моделями и сами модели
This commit is contained in:
@@ -48,3 +48,8 @@ docker-compose up
|
|||||||
`docker-compose exec web python manage.py createsuperuser`.
|
`docker-compose exec web python manage.py createsuperuser`.
|
||||||
|
|
||||||
Админ панель доступна тут: [http://127.0.0.1:8000/admin/](http://127.0.0.1:8000/admin/)
|
Админ панель доступна тут: [http://127.0.0.1:8000/admin/](http://127.0.0.1:8000/admin/)
|
||||||
|
|
||||||
|
Новые миграции добавляются и актуализируются командой
|
||||||
|
```bash
|
||||||
|
docker-compose exec web python manage.py makemigrations backend
|
||||||
|
```
|
||||||
|
|||||||
12
backend/backend/admin.py
Normal file
12
backend/backend/admin.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import ToDoList
|
||||||
|
|
||||||
|
|
||||||
|
class ToDoListAdmin(admin.ModelAdmin):
|
||||||
|
model = ToDoList
|
||||||
|
list_display = ["user", "title", "created_at"]
|
||||||
|
list_editable = ["title"]
|
||||||
|
|
||||||
|
|
||||||
|
admin.site.register(ToDoList, ToDoListAdmin)
|
||||||
20
backend/backend/api.py
Normal file
20
backend/backend/api.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from rest_framework import viewsets, serializers, permissions
|
||||||
|
from rest_framework import routers
|
||||||
|
|
||||||
|
from .models import ToDoList
|
||||||
|
|
||||||
|
|
||||||
|
class ToDoListSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = ToDoList
|
||||||
|
fields = ["title", "created_at"]
|
||||||
|
|
||||||
|
|
||||||
|
class ToDoListViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = ToDoList.objects.all()
|
||||||
|
serializer_class = ToDoListSerializer
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
router.register(r"lists", ToDoListViewSet)
|
||||||
6
backend/backend/apps.py
Normal file
6
backend/backend/apps.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class AppNameConfig(AppConfig):
|
||||||
|
name = "backend"
|
||||||
|
verbose_name = "ToDo List"
|
||||||
59
backend/backend/migrations/0001_initial.py
Normal file
59
backend/backend/migrations/0001_initial.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Generated by Django 3.2 on 2021-04-09 19:22
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="ToDoList",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("title", models.CharField(max_length=250)),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
default=None,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="ToDoItem",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("text", models.TextField()),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
(
|
||||||
|
"parent",
|
||||||
|
models.ForeignKey(
|
||||||
|
default=None,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="backend.todolist",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
0
backend/backend/migrations/__init__.py
Normal file
0
backend/backend/migrations/__init__.py
Normal file
14
backend/backend/models.py
Normal file
14
backend/backend/models.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from django.db import models
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
@@ -10,6 +10,7 @@ For the full list of settings and their values, see
|
|||||||
https://docs.djangoproject.com/en/3.2/ref/settings/
|
https://docs.djangoproject.com/en/3.2/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
@@ -31,12 +32,14 @@ ALLOWED_HOSTS = []
|
|||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
"backend.apps.AppNameConfig",
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
|
"rest_framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -94,9 +97,6 @@ DATABASES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
|
||||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
|
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||||
@@ -112,6 +112,15 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SIMPLE_JWT = {
|
||||||
|
"ACCESS_TOKEN_LIFETIME": timedelta(days=1), # не совсем подходит для JWT, но удобно
|
||||||
|
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
|
||||||
|
}
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
"DEFAULT_AUTHENTICATION_CLASSES": ("rest_framework_simplejwt.authentication.JWTAuthentication",)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.2/topics/i18n/
|
# https://docs.djangoproject.com/en/3.2/topics/i18n/
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
|
|
||||||
from rest_framework_simplejwt.views import (
|
from rest_framework_simplejwt.views import (
|
||||||
TokenObtainPairView,
|
TokenObtainPairView,
|
||||||
TokenRefreshView,
|
TokenRefreshView,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .api import router
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
|
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
|
||||||
path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
|
path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
|
||||||
|
path("api/", include(router.urls)),
|
||||||
|
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ services:
|
|||||||
db:
|
db:
|
||||||
image: postgres
|
image: postgres
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/db:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_DB=postgres
|
- POSTGRES_DB=postgres
|
||||||
- POSTGRES_USER=postgres
|
- POSTGRES_USER=postgres
|
||||||
@@ -18,3 +18,6 @@ services:
|
|||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
djangorestframework==3.12.4
|
||||||
|
markdown==3.3.4
|
||||||
appdirs==1.4.4
|
appdirs==1.4.4
|
||||||
asgiref==3.3.4
|
asgiref==3.3.4
|
||||||
certifi==2020.12.5
|
certifi==2020.12.5
|
||||||
|
|||||||
Reference in New Issue
Block a user