🔖 Справочник: сериализаторы DRF

⚡ Шпаргалка — сериализаторы DRF

# Базовый ModelSerializer
class XSerializer(serializers.ModelSerializer):
    class Meta:
        model = X
        fields = '__all__'

# Вложенный (только для чтения)
class XSerializer(serializers.ModelSerializer):
    related = RelatedSerializer(read_only=True)
    class Meta:
        model = X
        fields = '__all__'

# Только для записи (FK по ID)
class XCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = X
        fields = '__all__'

# Служебные поля только для чтения
class XSerializer(serializers.ModelSerializer):
    class Meta:
        model = X
        fields = '__all__'
        read_only_fields = ['created_at', 'deleted']

# Валидация поля
def validate_field_name(self, value):
    if not valid(value):
        raise serializers.ValidationError('Сообщение')
    return value

ModelSerializer — синтаксис Meta

Атрибут Meta Тип Описание
model class Django-модель
fields = '__all__' str Все поля модели
fields = [...] list Явный список нужных полей
exclude = [...] list Все поля, кроме указанных
read_only_fields = [...] list Поля только для чтения

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

# Для GET: объект полностью
class ProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer(read_only=True)
    supplier = SupplierSerializer(read_only=True)

    class Meta:
        model = Product
        fields = '__all__'
Важно: read_only=True обязателен для вложенных сериализаторов при чтении. Без него DRF будет пытаться принять вложенный объект при POST-запросе, что вызовет ошибку.

Ограничение полей для write-сериализатора

# Вариант 1: явный список
class CustomerCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = ['first_name', 'last_name', 'email', 'phone_number', 'address']

# Вариант 2: exclude для исключения служебных полей
class CustomerCreateUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        exclude = ['date_joined', 'deleted', 'deleted_at']

Паттерны кастомной валидации

import re

# Валидация телефона (10-15 цифр)
def validate_phone_number(self, value):
    if not re.match(r'^\d{10,15}$', value):
        raise serializers.ValidationError(
            'Номер телефона должен содержать от 10 до 15 цифр.'
        )
    return value

# Валидация числового диапазона
def validate_quantity(self, value):
    if value > 1000:
        raise serializers.ValidationError(
            'Количество товара должно быть не больше тысячи.'
        )
    return value

# Кросс-полевая валидация (общий метод)
def validate(self, data):
    if data['start'] > data['end']:
        raise serializers.ValidationError('start не может быть позже end')
    return data

Сериализаторы практикума 7 — таблица

Задача Класс Назначение
1CategorySerializerCRUD
2SupplierSerializerCRUD
3.1ProductSerializerЧтение + nested Category/Supplier
3.2ProductCreateUpdateSerializerЗапись (FK)
4.1ProductDetailSerializerЧтение + nested Product
4.2ProductDetailCreateUpdateSerializerЗапись (FK)
5AddressSerializerCRUD
6.1CustomerSerializerЧтение + nested Address + read_only_fields
6.2–6.3CustomerCreateUpdateSerializerЗапись + валидация телефона
7.1OrderSerializerЧтение + nested Customer + read_only_fields
7.2OrderCreateUpdateSerializerЗапись + read_only_fields
8.1OrderItemSerializerЧтение + nested Product/Order
8.2–8.3OrderItemCreateUpdateSerializerЗапись + валидация quantity
← К оглавлению урока    Примеры →