Как реализовать валидацию входных данных в Django Rest Framework

Ответ

В Django Rest Framework (DRF) валидация данных является ключевой функцией сериализаторов. Существует несколько уровней для её реализации:

  1. Валидация на уровне поля. Это базовый уровень, где проверка применяется к одному полю с помощью встроенных аргументов (required, max_length, min_value) или кастомных валидаторов.

    from rest_framework import serializers
    from django.core.validators import RegexValidator
    
    class ProductSerializer(serializers.Serializer):
        name = serializers.CharField(max_length=100)
        price = serializers.DecimalField(max_digits=10, decimal_places=2, min_value=0)
        sku = serializers.CharField(validators=[RegexValidator(r'^SKU-d{5}$')])
  2. Метод validate_<field_name>() Для более сложной логики валидации конкретного поля в классе сериализатора определяется метод с префиксом validate_.

    class EventSerializer(serializers.Serializer):
        # ... другие поля
        event_name = serializers.CharField()
    
        def validate_event_name(self, value):
            if "free" in value.lower():
                raise serializers.ValidationError("Название события не должно содержать 'free'.")
            return value
  3. Метод validate() Для валидации, затрагивающей несколько полей одновременно (кросс-филд валидация), используется метод validate().

    class BookingSerializer(serializers.Serializer):
        start_date = serializers.DateField()
        end_date = serializers.DateField()
    
        def validate(self, data):
            if data['start_date'] > data['end_date']:
                raise serializers.ValidationError("Дата окончания не может быть раньше даты начала.")
            return data

Эти уровни позволяют выстраивать гибкую и многоуровневую систему проверки данных, от простых ограничений до сложной бизнес-логики.

Ответ 18+ 🔞

Ах, валидация в DRF, ну классика же! Это как проверять, не забыл ли ты штаны надеть, выходя из дома — уровней дохуя, и каждый следующий всё строже. Смотри, как тут всё устроено, блядь.

Первый уровень — это как бабушка на пороге: "Куда без шапки?" То есть, проверки прямо в объявлении поля. Максимальная длина, минимальное значение, регулярки эти ваши. Просто и в лоб.

from rest_framework import serializers
from django.core.validators import RegexValidator

class ProductSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=100) # Больше 100 символов? Иди нахуй.
    price = serializers.DecimalField(max_digits=10, decimal_places=2, min_value=0) # Отрицательная цена? Да ты, блядь, бизнесмен!
    sku = serializers.CharField(validators=[RegexValidator(r'^SKU-d{5}$')]) # Не по шаблону? Пизда твоей артикуляции.

Второй уровень — уже личная придирка к одному полю. Типа, метод validate_<имя_поля>(). Тут можно вьебать свою логику, которая в стандартные аргументы не влезает.

class EventSerializer(serializers.Serializer):
    # ... прочие поля
    event_name = serializers.CharField()

    def validate_event_name(self, value):
        # "Бесплатный вебинар" — это, блядь, подозрительно.
        if "free" in value.lower():
            raise serializers.ValidationError("Название события не должно содержать 'free'.")
        return value # Иначе ок, проходи.

Третий уровень — это уже полный разбор полётов, кросс-филд валидация. Метод validate(). Когда нужно сравнить одно поле с другим, и если хуйня выходит — наехать на всю отправку данных сразу.

class BookingSerializer(serializers.Serializer):
    start_date = serializers.DateField()
    end_date = serializers.DateField()

    def validate(self, data):
        # Чего блядь? Кончиться раньше, чем начаться?
        if data['start_date'] > data['end_date']:
            raise serializers.ValidationError("Дата окончания не может быть раньше даты начала.")
        return data # Иначе всё пучком, валидируй дальше.

Вот и вся магия, ёпта. Сначала поле само по себе, потом к нему пристают отдельно, а потом вся форма целиком летит на проверку. Как в хорошем анекдоте: сначала смешно, потом страшно, а потом опять смешно, но уже сквозь слёзы. Главное — порядок соблюдать, а то наебнёшься с валидацией на раз.