⚖️ Старый vs Новый: сериализаторы DRF
⚡ Ключевые изменения
- DRF 3.x+:
ModelSerializerподдерживаетread_only_fieldsпрямо в Meta - Старый стиль: переопределять поля вручную через
serializers.Field(read_only=True) - DRF 3.15+: улучшена типизация и поддержка
extra_kwargs extra_kwargs— альтернатива явному переопределению полей
1. Явное определение полей vs ModelSerializer
Старый подход (из лекции)
# Вручную перечислять каждое поле
class CategorySerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=100)
description = serializers.CharField(
required=False
)
def create(self, validated_data):
return Category.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.save()
return instance
Современный подход (DRF 3.x)
# ModelSerializer автогенерирует поля из модели
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
# create() и update() — встроены,
# не нужно переопределять
2. read_only через extra_kwargs vs явное определение
Старый подход
class CustomerSerializer(serializers.ModelSerializer):
# Явное переопределение поля
date_joined = serializers.DateTimeField(
read_only=True
)
deleted = serializers.BooleanField(
read_only=True
)
class Meta:
model = Customer
fields = '__all__'
Современный подход (из лекции)
class CustomerSerializer(serializers.ModelSerializer):
address = AddressSerializer(read_only=True)
class Meta:
model = Customer
fields = '__all__'
# Компактно — список в Meta
read_only_fields = [
'date_joined', 'deleted', 'deleted_at'
]
3. extra_kwargs — альтернатива read_only_fields
Начиная с DRF 3.x доступен атрибут extra_kwargs для тонкой настройки полей без явного переопределения:
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = '__all__'
extra_kwargs = {
'order_date': {'read_only': True},
'customer': {'required': True},
}
# Эквивалентно read_only_fields = ['order_date']
# но позволяет задавать любые kwargs полям
Что использовать: Для простого
read_only — read_only_fields читаемее. Для множества разных настроек полей — extra_kwargs компактнее.
4. Валидация: validators list vs validate_field
Старый подход (DRF < 3.x)
# Отдельный класс валидатора
class PhoneValidator:
def __call__(self, value):
if not re.match(r'^\d{10,15}$', value):
raise ValidationError('...')
class CustomerSerializer(serializers.ModelSerializer):
phone_number = serializers.CharField(
validators=[PhoneValidator()]
)
Современный подход (из лекции)
# Метод прямо в сериализаторе
class CustomerCreateUpdateSerializer(
serializers.ModelSerializer
):
class Meta:
model = Customer
fields = [...]
def validate_phone_number(self, value):
if not re.match(r'^\d{10,15}$', value):
raise serializers.ValidationError('...')
return value
⚠️ Проверить по документации: DRF 3.15+ вводит улучшенную поддержку типизации через аннотации. Сериализаторы теперь совместимы с mypy/pyright при использовании
drf-stubs.