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`.
|
||||
|
||||
Админ панель доступна тут: [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/
|
||||
"""
|
||||
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
@@ -31,12 +32,14 @@ ALLOWED_HOSTS = []
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"backend.apps.AppNameConfig",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -94,9 +97,6 @@ DATABASES = {
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"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
|
||||
# https://docs.djangoproject.com/en/3.2/topics/i18n/
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from django.urls import path, include
|
||||
|
||||
from rest_framework_simplejwt.views import (
|
||||
TokenObtainPairView,
|
||||
TokenRefreshView,
|
||||
)
|
||||
|
||||
from .api import router
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
|
||||
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:
|
||||
image: postgres
|
||||
volumes:
|
||||
- ./data/db:/var/lib/postgresql/data
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
@@ -18,3 +18,6 @@ services:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
djangorestframework==3.12.4
|
||||
markdown==3.3.4
|
||||
appdirs==1.4.4
|
||||
asgiref==3.3.4
|
||||
certifi==2020.12.5
|
||||
|
||||
Reference in New Issue
Block a user