⚡ Топ-команды
pip install djangorestframework # установка DRF
python manage.py runserver # запуск сервера
# ORM — агрегация
Book.objects.aggregate(total=Count('id'), avg=Avg('price'))
Book.objects.values('author').annotate(cnt=Count('id'))
Book.objects.order_by('-price')[:5]
# DRF — сериализатор
serializer = BookSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
# DRF — ViewSet + Router
router = DefaultRouter()
router.register(r'books', BookViewSet)
# query_params
request.query_params.get('author', '')
ORM — агрегация и аннотации
| Метод / функция | Описание | Пример |
aggregate(**kwargs) | Вычисляет значения по всему QuerySet, возвращает словарь | Book.objects.aggregate(n=Count('id')) |
annotate(**kwargs) | Добавляет вычисленное поле к каждому объекту | .values('author').annotate(cnt=Count('id')) |
Count(field) | Количество записей | Count('id') |
Sum(field) | Сумма значений | Sum('price') |
Avg(field) | Среднее значение | Avg('price') |
Min(field) | Минимальное значение | Min('price') |
Max(field) | Максимальное значение | Max('price') |
order_by(*fields) | Сортировка; «-» — убывание | .order_by('-price', 'title') |
qs[start:stop] | Срез QuerySet (LIMIT/OFFSET в SQL) | .all()[:10] |
Subquery(qs) | Подзапрос внутри QuerySet | см. examples.html |
OuterRef(field) | Ссылка на поле внешнего запроса | OuterRef('author') |
ExpressionWrapper(expr, output_field) | Обёртка для сложного выражения с явным типом | ExpressionWrapper(F('a')/F('b'), FloatField()) |
DRF — сериализаторы
| Метод / атрибут | Описание |
serializer.is_valid() | Валидирует данные; возвращает True/False |
serializer.is_valid(raise_exception=True) | То же, но бросает ValidationError при ошибке |
serializer.validated_data | Словарь с провалидированными данными |
serializer.errors | Словарь с ошибками валидации |
serializer.save() | Вызывает create() или update() |
serializer.data | Сериализованное представление (для ответа) |
Meta.fields = '__all__' | Включить все поля модели |
Meta.exclude = [...] | Исключить указанные поля |
Meta.read_only_fields = [...] | Поля только для чтения |
validate_<field>(value) | Валидация отдельного поля |
validate(data) | Валидация нескольких полей одновременно |
DRF — представления и статус-коды
| Элемент | Описание |
@api_view(['GET', 'POST']) | Декоратор для FBV — указывает разрешённые HTTP-методы |
Response(data, status=...) | Ответ DRF с автоматическим content-negotiation |
request.data | Тело запроса (JSON → dict) |
request.query_params | GET-параметры запроса (аналог request.GET) |
status.HTTP_200_OK | 200 — успешный GET |
status.HTTP_201_CREATED | 201 — объект создан |
status.HTTP_204_NO_CONTENT | 204 — успешное удаление |
status.HTTP_400_BAD_REQUEST | 400 — ошибка валидации |
status.HTTP_404_NOT_FOUND | 404 — объект не найден |
DRF — Generic views
| Класс | Методы | Типичный URL |
ListAPIView | GET | /books/ |
CreateAPIView | POST | /books/ |
ListCreateAPIView | GET, POST | /books/ |
RetrieveAPIView | GET | /books/<pk>/ |
UpdateAPIView | PUT, PATCH | /books/<pk>/ |
DestroyAPIView | DELETE | /books/<pk>/ |
RetrieveUpdateDestroyAPIView | GET, PUT, PATCH, DELETE | /books/<pk>/ |
ModelViewSet | GET, POST, PUT, PATCH, DELETE | /books/ + /books/<pk>/ |
DRF — Router
from rest_framework.routers import DefaultRouter
from .views import BookViewSet
router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book')
# В urls.py:
urlpatterns = router.urls
# Генерирует автоматически:
# GET /books/ -> list
# POST /books/ -> create
# GET /books/{pk}/ -> retrieve
# PUT /books/{pk}/ -> update
# PATCH /books/{pk}/ -> partial_update
# DELETE /books/{pk}/ -> destroy