Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Сериализаторы
serializers

Сериализаторы

Базовые сериализаторы, ModelSerializer, валидация, вложенные сериализаторы

Сериализаторы в Django REST Framework

Сериализаторы — это сердце DRF. Они преобразуют сложные объекты (модели Django) в простые типы данных для JSON и обратно.

#Что такое сериализация

Сериализация — процесс преобразования объекта в формат, который можно легко передать по сети (JSON, XML). Десериализация — обратный процесс.

# Сериализация: объект Python → JSON article = Article.objects.get(pk=1) serializer = ArticleSerializer(article) print(serializer.data) # {'id': 1, 'title': '...', ...} # Десериализация: JSON → объект Python data = {'title': 'Новая статья', 'content': 'Текст'} serializer = ArticleSerializer(data=data) if serializer.is_valid(): article = serializer.save()

#Базовый Serializer

Можно создать сериализатор вручную, определив все поля:

from rest_framework import serializers class ArticleSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) title = serializers.CharField(max_length=200) content = serializers.CharField() author = serializers.PrimaryKeyRelatedField(queryset=User.objects.all()) 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.content = validated_data.get('content', instance.content) instance.save() return instance

Недостатки:

  • Много повторяющегося кода
  • Нужно вручную определять create() и update()
  • При изменении модели нужно обновлять сериализатор

#ModelSerializer

ModelSerializer автоматически создаёт поля на основе модели:

class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['id', 'title', 'content', 'author', 'created_at'] # или fields = '__all__' для всех полей

Преимущества:

  • Автоматическое создание полей
  • Готовые create() и update()
  • Валидация на основе модели

#Поля сериализатора

#Типы полей

class ExampleSerializer(serializers.Serializer): # Строковые char_field = serializers.CharField(max_length=100) email = serializers.EmailField() url = serializers.URLField() slug = serializers.SlugField() # Числовые integer = serializers.IntegerField() float_field = serializers.FloatField() decimal = serializers.DecimalField(max_digits=10, decimal_places=2) # Дата и время date = serializers.DateField() time = serializers.TimeField() datetime = serializers.DateTimeField() duration = serializers.DurationField() # Булевы boolean = serializers.BooleanField() null_boolean = serializers.BooleanField(allow_null=True) # Выбор вариантов choice = serializers.ChoiceField(choices=[('a', 'Option A'), ('b', 'Option B')]) # Файлы file = serializers.FileField() image = serializers.ImageField() # Связи foreign_key = serializers.PrimaryKeyRelatedField(queryset=OtherModel.objects.all()) many_to_many = serializers.ManyRelatedField(child=serializers.PrimaryKeyRelatedField(...)) # Прочие json_field = serializers.JSONField() readonly = serializers.CharField(read_only=True)

#Валидация данных

#Валидация на уровне поля

Метод validate_<field>() вызывается для конкретного поля:

class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['title', 'content', 'price'] def validate_title(self, value): """Проверка заголовка""" if len(value) < 5: raise serializers.ValidationError("Заголовок слишком короткий") if Article.objects.filter(title=value).exists(): raise serializers.ValidationError("Такой заголовок уже существует") return value def validate_price(self, value): """Проверка цены""" if value <= 0: raise serializers.ValidationError("Цена должна быть положительной") return value

#Валидация на уровне объекта

Метод validate() проверяет несколько полей одновременно:

def validate(self, data): """Проверка нескольких полей""" if data.get('title') and data.get('content'): if data['title'] in data['content']: raise serializers.ValidationError( "Заголовок не должен содержаться в тексте статьи" ) return data

#Read-only и Write-only поля

class UserSerializer(serializers.ModelSerializer): # Только для чтения — отображается в ответе, но не принимается created_at = serializers.DateTimeField(read_only=True) # Только для записи — принимается, но не отображается password = serializers.CharField(write_only=True, min_length=8) # Через extra_kwargs class Meta: model = User fields = ['id', 'username', 'email', 'created_at', 'password'] read_only_fields = ['created_at', 'id'] extra_kwargs = { 'password': {'write_only': True}, 'email': {'required': True}, }

#Вложенные сериализаторы

#Чтение связанных данных

class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ['id', 'name', 'email'] class BookSerializer(serializers.ModelSerializer): author = AuthorSerializer(read_only=True) # Вложенный сериализатор author_id = serializers.PrimaryKeyRelatedField( queryset=Author.objects.all(), source='author', write_only=True ) class Meta: model = Book fields = ['id', 'title', 'author', 'author_id']

Результат:

{ "id": 1, "title": "Python Guide", "author": { "id": 5, "name": "John Doe", "email": "john@example.com" } }

#Запись связанных данных

class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['id', 'title', 'author'] def create(self, validated_data): # author уже является объектом Author благодаря PrimaryKeyRelatedField return Book.objects.create(**validated_data)

#SerializerMethodField

Поле, значение которого вычисляется методом:

class ArticleSerializer(serializers.ModelSerializer): author_name = serializers.SerializerMethodField() is_recent = serializers.SerializerMethodField() class Meta: model = Article fields = ['id', 'title', 'author_name', 'is_recent'] def get_author_name(self, obj): return obj.author.username def get_is_recent(self, obj): from datetime import timedelta recent = timezone.now() - timedelta(days=7) return obj.created_at > recent

Правило: Метод должен называться get_<field_name>(self, obj).

#Контекст сериализатора

Контекст передаёт дополнительные данные (например, request):

# В view serializer = ArticleSerializer(article, context={'request': request}) # В сериализаторе class ArticleSerializer(serializers.ModelSerializer): url = serializers.SerializerMethodField() is_owner = serializers.SerializerMethodField() class Meta: model = Article fields = ['id', 'title', 'url', 'is_owner'] def get_url(self, obj): request = self.context['request'] return request.build_absolute_uri(obj.get_absolute_url()) def get_is_owner(self, obj): request = self.context['request'] return obj.author == request.user

#Глубина вложенности

Можно автоматически сериализовать связанные объекты:

class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = '__all__' depth = 1 # Автоматически сериализует связанные объекты на 1 уровень

Недостаток: Меньше контроля над выводом. Лучше использовать явные вложенные сериализаторы.

#Динамические поля

Можно изменять поля сериализатора динамически:

class DynamicFieldsSerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): fields = kwargs.pop('fields', None) super().__init__(*args, **kwargs) if fields is not None: allowed = set(fields) existing = set(self.fields) for field_name in existing - allowed: self.fields.pop(field_name) # Использование serializer = DynamicFieldsSerializer(article, fields=['id', 'title'])

#Best Practices

  1. Используйте ModelSerializer по умолчанию — это экономит время
  2. Явно указывайте поля вместо fields = '__all__' для контроля API
  3. Разделяйте сериализаторы для чтения и записи, если логика отличается
  4. Используйте select_related в view для оптимизации запросов к связанным полям
  5. Валидируйте на уровне модели через unique_together, constraints
  6. Документируйте поля через help_text в модели или сериализаторе

Далее: Представления