⚖️ Старый vs Новый подходы
⚡ Главные отличия
- Enum choices: кастомный Python Enum → встроенный
models.TextChoices/IntegerChoices - unique_together: устаревший Meta-атрибут →
UniqueConstraintвMeta.constraints - get_object_or_404: из
rest_framework.generics→ изrest_framework.generics(не из Django shortcuts в DRF) - HTTP 204 vs 200: пустой список → возвращать 200 с
[], а не 204
1. Enum choices: кастомный vs встроенный
Из лекции (кастомный Enum)
from enum import Enum
class Statuses(Enum):
NEW = "NEW"
IN_PROGRESS = "IN_PROGRESS"
CLOSED = "CLOSED"
@classmethod
def choices(cls):
return [(attr.name, attr.value)
for attr in cls]
# В модели:
status = models.CharField(
max_length=15,
choices=Statuses.choices,
default=Statuses.NEW
)
Современный Django 3.0+ TextChoices
from django.db import models
class Statuses(models.TextChoices):
NEW = "NEW", "Новая"
IN_PROGRESS = "IN_PROGRESS", "В работе"
CLOSED = "CLOSED", "Закрыта"
# В модели:
status = models.CharField(
max_length=15,
choices=Statuses.choices,
default=Statuses.NEW
)
Преимущества TextChoices: встроен в Django, автодополнение IDE, метки (verbose names) «из коробки», нет необходимости в методе choices().
⚠️ Проверить по документации:
models.TextChoices доступен с Django 3.0. Для целочисленных значений — models.IntegerChoices.2. unique_together vs UniqueConstraint
Из лекции (устаревший)
class Meta:
unique_together = ('name', 'project')
Современный Django 2.2+
from django.db.models import UniqueConstraint
class Meta:
constraints = [
UniqueConstraint(
fields=['name', 'project'],
name='unique_task_per_project'
)
]
unique_together задеприкейтирован в Django 4.2 и будет удалён в будущих версиях. UniqueConstraint даёт именованные ограничения и поддержку условных индексов.
3. HTTP 204 No Content для пустых списков
Из лекции
if not tags.exists():
return Response(
data=[],
status=status.HTTP_204_NO_CONTENT
)
REST-конвенция (RFC 7231)
# 204 означает «ответ без тела»,
# а не «пустой список»
# Правильно: 200 + пустой массив
return Response(
data=[],
status=status.HTTP_200_OK
)
Статус 204 No Content семантически означает «операция выполнена, тело ответа отсутствует» (типично для DELETE). Для GET-запроса с пустым результатом корректнее возвращать 200 OK с пустым массивом [].
4. Плоская структура vs модуль apps/
Стандартная структура Django
myproject/
tasks/ ← приложение в корне
models.py
views.py
projects/
models.py
views.py
Архитектура проекта (из лекции)
myproject/
apps/ ← модуль-контейнер
__init__.py
tasks/
models/ ← подмодуль моделей
views/
projects/
models/
views/
Вынесение приложений в модуль apps/ — рекомендуемый паттерн для больших проектов. Позволяет избежать конфликтов имён и упрощает навигацию.