Что такое Django REST Framework (DRF) и как работают сериализаторы?
DRF — библиотека для построения REST API на Django; сериализаторы преобразуют модели в JSON и обратно, выполняют валидацию через is_valid() и сохраняют данные через save(), вызывающий create() или update().
Что такое Django REST Framework
Django REST Framework (DRF) — это библиотека поверх Django, предоставляющая инструменты для построения Web API: сериализаторы, generic views, viewsets, routers, аутентификацию, пермиссии и пагинацию. Устанавливается через pip и регистрируется в INSTALLED_APPS.
pip install djangorestframework
# settings.py
INSTALLED_APPS = [
...
"rest_framework",
]
Что делают сериализаторы
Сериализатор выполняет три задачи:
- Сериализация — преобразует Python-объект (модель Django, queryset) в примитивный словарь, который затем JSON-энкодер превращает в байты.
- Десериализация и валидация — принимает входные данные (из запроса), проверяет их и возвращает очищенные значения через
validated_data. - Сохранение — через методы
create()иupdate()записывает данные в базу.
Базовый Serializer
from rest_framework import serializers
class ArticleSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(max_length=255)
published = serializers.BooleanField(default=False)
created_at = serializers.DateTimeField(read_only=True)
def create(self, validated_data):
return Article.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get("title", instance.title)
instance.published = validated_data.get("published", instance.published)
instance.save()
return instance
ModelSerializer — быстрый путь
ModelSerializer автоматически генерирует поля из модели Django, избавляя от ручного перечисления. Достаточно указать модель и список полей.
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ["id", "title", "published", "created_at"]
read_only_fields = ["id", "created_at"]
def validate_title(self, value):
"""Валидация одного поля."""
if len(value) < 5:
raise serializers.ValidationError("Title must be at least 5 characters.")
return value
def validate(self, attrs):
"""Кросс-полевая валидация."""
if attrs.get("published") and not attrs.get("title"):
raise serializers.ValidationError("Published articles must have a title.")
return attrs
Использование сериализатора в view
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer
@api_view(["GET", "POST"])
def article_list(request):
if request.method == "GET":
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
elif request.method == "POST":
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid():
serializer.save() # вызывает create()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Вложенные сериализаторы и связи
Для ForeignKey и M2M DRF предоставляет несколько вариантов представления: первичный ключ (PrimaryKeyRelatedField), строковое представление (StringRelatedField) или вложенный сериализатор.
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ["id", "name"]
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only=True) # вложенный объект
author_id = serializers.PrimaryKeyRelatedField(
queryset=Author.objects.all(), source="author", write_only=True
)
class Meta:
model = Article
fields = ["id", "title", "author", "author_id"]
Подводные камни
- N+1 запросы с вложенными сериализаторами. Каждый вложенный объект без
select_related/prefetch_relatedгенерирует отдельный SQL-запрос. Всегда оптимизируйте queryset в view. - fields = "__all__" в Meta. Удобно для прототипа, но легко случайно экспонировать чувствительные поля (пароль, токены). Всегда явно перечисляйте поля.
- is_valid() без raise_exception. Если забыть вызвать
is_valid()перед обращением кvalidated_data, Django броситAssertionError. Используйтеserializer.is_valid(raise_exception=True)в API-views. - create()/update() не вызываются автоматически.
save()вызывает их косвенно; если нужна транзакция, оберните вtransaction.atomic()внутри метода. - Вложенная запись без кастомных create/update. DRF по умолчанию не умеет создавать связанные объекты через вложенные сериализаторы при записи — нужно переопределять методы вручную.
- SerializerMethodField и производительность. Каждое поле типа
SerializerMethodFieldвызывает Python-функцию на каждый объект; при большом queryset это заметно.
Common mistakes
- Описывать drf serializers только как термин и не показывать механизм на минимальном примере.
- Игнорировать ошибки, пустые данные, конкурентный доступ или границы транзакции.
- Не связывать поведение с официальным контрактом Django и реальной эксплуатацией.
What the interviewer is testing
- Объясняет drf serializers через последовательность действий, а не через набор ключевых слов.
- Приводит короткий кодовый пример или production-сценарий с ожидаемым поведением.
- Называет хотя бы один риск: производительность, безопасность, транзакции, память или сопровождение.