Чтобы убедиться, что хотя бы одно из полей `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`, создание экземпляра пройдет успешно.