# Базовый 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