Как в Pydantic реализовать кастомную логику валидации для полей модели

Ответ

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

Валидаторы необходимы для реализации сложных бизнес-правил, которые невозможно описать стандартными типами данных (например, проверка сложности пароля или формата номера телефона).

Пример полевого валидатора:

from pydantic import BaseModel, validator, ValidationError

class UserRegistration(BaseModel):
    username: str
    age: int

    # Валидатор для поля 'age'
    @validator('age')
    def check_age_is_adult(cls, v):
        # 'v' - это значение поля age
        if v < 18:
            raise ValueError('Пользователь должен быть старше 18 лет')
        return v # Валидатор всегда должен возвращать значение

try:
    # Успешная валидация
    user_ok = UserRegistration(username='john_doe', age=25)
    print(user_ok)
    # > username='john_doe' age=25

    # Ошибка валидации
    user_fail = UserRegistration(username='jane_doe', age=16)
except ValidationError as e:
    print(e)
    # > 1 validation error for UserRegistration
    # > age
    # >   Пользователь должен быть старше 18 лет (type=value_error)

Основные возможности валидаторов:

  • Применение к нескольким полям: @validator('field1', 'field2').
  • Предварительная валидация: @validator('field', pre=True) выполняет проверку до стандартной обработки Pydantic. Полезно для приведения типов.
  • Валидация всей модели: Декоратор @root_validator позволяет реализовать логику, зависящую от нескольких полей одновременно (например, проверка, что password_confirm совпадает с password).
  • Повторное использование: Валидаторы можно выносить в отдельные функции и импортировать.