Как проверить, что хотя бы одно из нескольких полей не содержит значения None?

Как можно сделать проверку, чтобы убедиться, что хотя бы одно из полей username, email или phone не равно None в модели LoginRequest при использовании Pydantic для валидации данных?
  • 24 января 2024 г. 15:18
Ответы на вопрос 2
Чтобы убедиться, что хотя бы одно из полей `username`, `email` или `phone` не равно `None` при использовании Pydantic для валидации данных, вы можете использовать методы валидации, предоставляемые Pydantic. Во-первых, создадим модель `LoginRequest` с использованием Pydantic:

```python
from pydantic import BaseModel, validator

class LoginRequest(BaseModel):
    username: str = None
    email: str = None
    phone: str = None

    @validator('username', 'email', 'phone', pre=True, each_item=True)
    def check_at_least_one_not_none(cls, v, values, **kwargs):
        if v is not None:
            return v
        if all(value is None for field, value in values.items() if field != 'phone'):
            # Все остальные поля None, значит ничего не было предоставлено.
            raise ValueError('At least one of username, email or phone must be provided')
        return v
```

В этом примере, мы определили класс `LoginRequest` с тремя полями: `username`, `email` и `phone`. Каждое поле по умолчанию установлено в `None`.

Метод `validator` используется для добавления пользовательской функции валидации. Аргументы `pre=True` и `each_item=True` указывают Pydantic проверять значения до того, как произойдет основное присвоение и применять валидатор для каждого из указанных полей.

Функция валидации `check_at_least_one_not_none` проверяет, что хотя бы одно из полей не `None`. Если все три поля равны `None`, то возбуждается `ValueError` с сообщением об ошибке.

Обратите внимание, что в функции `check_at_least_one_not_none` используется параметр `values`, который содержит словарь уже проверенных и обработанных значений до текущего поля. Из-за `pre=True`, это означает, что на момент использования `values` для поля `username`, он будет содержать только значение `username` (с `None` или без), для поля `email` он будет содержать значения `username` и `email`, и так далее. Такой подход позволяет делать проверки, касающиеся нескольких полей одновременно.

Используйте созданную модель следующим образом:

```python
try:
    login_request = LoginRequest(username=None, email=None, phone=None)
except ValueError as e:
    print(e)

try:
    login_request = LoginRequest(username='myusername', email=None, phone=None)
    print(login_request)
except ValueError as e:
    print(e)
```

Если вы попытаетесь создать экземпляр модели `LoginRequest` с `None` во всех трех полях, будет вызвано исключение `ValueError`. Если хотя бы в одном поле есть значение, отличное от `None`, создание экземпляра пройдет успешно.
Давайте вместе почитаем документацию 

Похожие вопросы