У контексті Pydantic і FastAPI обов'язкові поля — це ті, які повинні бути надані користувачем у запиті. Якщо такі поля відсутні, FastAPI одразу поверне помилку з детальним описом того, чого саме не вистачає.
Опціональні поля, навпаки, можуть бути або присутні, або відсутні. Якщо їх нема в запиті, система не впаде, а просто використає значення за замовчуванням або залишить це поле порожнім.
Де це застосовується?
- Обов'язкові поля: наприклад, у додатку для реєстрації користувача зазвичай важливо, щоб поля
usernameіpasswordбули присутні. Без них ніяк. - Опціональні поля: якщо в формі реєстрації є поле
middle_name(по-батькові), то цілком логічно, що не всі захочуть його вказувати.
Використання Pydantic для роботи з обов'язковими полями
Давайте почнемо з самого базового прикладу найпростіші моделі з обов'язковими полями.
from pydantic import BaseModel
class User(BaseModel):
username: str
email: str
age: int
У цій моделі поля username, email і age є обов'язковими. Якщо хоча б одне з них відсутнє в даних, надісланих в наш API, FastAPI поверне таку помилку:
{
"detail": [
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
Як працює валідація обов'язкових полів
Pydantic автоматично валідовує, що всі вказані поля присутні і відповідають своїм типам. Наприклад:
- Поле
usernameмає бути рядком (типstr). - Поле
ageмає бути цілим числом (типint).
Робота з опціональними полями
Щоб створити опціональне поле, воно має або:
- мати значення за замовчуванням.
- задати тип у вигляді об'єднання типів, наприклад
str | None.
Ось приклад:
from pydantic import BaseModel
class User(BaseModel):
username: str
email: str
middle_name: str | None = None # Поле може бути відсутнє
Тут поле middle_name опціональне, бо ми вказали тип str | None і задали значення за замовчуванням (None).
Приклад використання опціональних полів
Ось як це буде працювати на практиці:
- Якщо користувач надішле JSON:
Тоді FastAPI обробить запит без проблем, навіть якщо{ "username": "john_doe", "email": "john@example.com" }middle_nameне вказане. - Якщо користувач все ж таки вкаже
middle_name:
Тоді{ "username": "john_doe", "email": "john@example.com", "middle_name": "Edward" }middle_nameбуде містити значення"Edward".
Порівняння обов'язкових і опціональних полів
| Поле | Приклад коду | Коли потрібно? |
|---|---|---|
| Обов'язкове поле | username: str |
Дані критично важливі для роботи моделі |
| Опціональне поле | middle_name: str | None = None |
Дані можуть відсутні в запиті |
| З дефолтним значенням | is_active: bool = True |
Використовується значення за замовчуванням, якщо поле пусте |
Занурюємося глибше: робота з Required і значеннями за замовчуванням
Якщо ви хочете, щоб поле було опціональним і мало значення за замовчуванням, достатньо просто задати це значення в моделі:
class User(BaseModel):
is_active: bool = True # Значення за замовчуванням — True
Тепер навіть якщо користувач не надасть is_active, воно все одно автоматично встановиться в значення True.
Якщо ви хочете бути максимально суворими, можете вказати, що поле не може бути порожнім, використовуючи ... (три крапки):
from pydantic import Required
class Product(BaseModel):
name: str = Field(..., description="Назва продукту")
price: float
Тепер name став абсолютно обов'язковим: FastAPI ніколи не пропустить його відсутність.
Приклади з реального життя
Приклад 1: реєстрація користувача
Додамо обов'язкові та опціональні поля в endpoint реєстрації нового користувача.
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class User(BaseModel):
username: str
email: EmailStr
middle_name: str | None = None
age: int
is_active: bool = True # Значення за замовчуванням
@app.post("/register")
async def register_user(user: User):
return {"message": f"User {user.username} registered successfully!"}
Тестуємо цей endpoint:
- Якщо надішлемо:
Відповідь буде:{ "username": "john_doe", "email": "john@example.com", "age": 25 }{ "message": "User john_doe registered successfully!" } - Якщо приберемо
username:
API поверне помилку:{ "email": "john@example.com", "age": 25 }{ "detail": [ { "loc": ["body", "username"], "msg": "field required", "type": "value_error.missing" } ] }
Приклад 2: фільтрація товарів
Додамо опціональний параметр для фільтрації списку товарів.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class ProductFilter(BaseModel):
category: str | None = None
min_price: float | None = None
max_price: float | None = None
@app.get("/products")
async def filter_products(filter: ProductFilter):
return {"filter": filter.dict()}
Такий endpoint дозволяє фільтрувати товари за допомогою опціональних параметрів. Користувач може надати частину даних, наприклад, тільки категорію або мінімальну ціну.
Типові помилки та особливості роботи
Часта помилка — забути вказати значення за замовчуванням для опціонального поля. Наприклад:
class User(BaseModel):
middle_name: str | None # Помилка! Немає значення за замовчуванням!
Таке поле стане обов'язковим, незважаючи на використання Optional. Тому завжди додавайте = None, якщо поле має бути опціональним.
Ще одна помилка — спроба поєднати Required і дефолтне значення. Якщо поле має значення за замовчуванням, воно вже не вважається суворо обов'язковим.
На цьому все на сьогодні, друзі! Тепер ваші форми, запити та моделі будуть структуровані, як банківський звіт, і ніхто не пропустить заповнення важливих даних. А ви — на крок ближче до статусу майстра FastAPI!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ