⚖️ Старый 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_onlyread_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.
← К оглавлению урока    Задания →