Привет! FastAPI использует Pydantic для валидации данных. Это одна из самых мощных фишек фреймворка — данные автоматически проверяются, преобразуются и документируются.
В этой статье мы разберём:
- Что такое Pydantic модели
- Создание моделей
- Валидация данных
- Вложенные модели
- Опциональные поля
- Что нужно знать перед началом
- Основная часть
- Что такое Pydantic
- Создание модели
- Валидация типов
- Опциональные поля
- Вложенные модели
- Списки в моделях
- Валидация полей
- Валидация через валидаторы
- Полный пример
- Задачи для закрепления
- Нюансы и подводные камни
- Частые ошибки и как их избежать
- Ошибка 1: Забыл импортировать Field
- Ошибка 2: Неправильная валидация вложенных моделей
- Ошибка 3: Использование @validator без values для кросс-полей
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный FastAPI
- Базовое понимание классов Python
Совет: Pydantic — это основа FastAPI. Без него невозможно представить работу с данными.
Основная часть
Что такое Pydantic
Pydantic — это библиотека для валидации данных с помощью аннотаций типов Python.
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
email: strСовет: Pydantic автоматически валидирует типы и преобразует данные.
Создание модели
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str = None # Опциональное поле
tax: float = 0.0
@app.post("/items/")
def create_item(item: Item):
return {"item": item}Совет: Поля со значениями по умолчанию становятся опциональными.
Валидация типов
Pydantic автоматически проверяет типы.
class User(BaseModel):
name: str
age: int
is_active: bool = True
# Правильно
user = User(name="Анна", age=25, is_active=True)
# Ошибка! age должен быть int
# user = User(name="Анна", age="25")Опциональные поля
from typing import Optional
class User(BaseModel):
name: str
age: Optional[int] = None
city: Optional[str] = NoneВложенные модели
class Address(BaseModel):
street: str
city: str
zip_code: str
class User(BaseModel):
name: str
age: int
address: Address
@app.post("/users/")
def create_user(user: User):
return {"user": user}Пример запроса:
{
"name": "Анна",
"age": 25,
"address": {
"street": "ул. Ленина, 1",
"city": "Москва",
"zip_code": "123456"
}
}Списки в моделях
from typing import List
class Order(BaseModel):
id: int
items: List[str]
prices: List[float]
@app.post("/orders/")
def create_order(order: Order):
return {"order": order}Пример запроса:
{
"id": 1,
"items": ["Ноутбук", "Телефон"],
"prices": [1000.0, 500.0]
}Валидация полей
from pydantic import BaseModel, Field
class User(BaseModel):
name: str = Field(..., min_length=2, max_length=50)
age: int = Field(..., ge=0, le=120)
email: str = Field(..., regex=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
@app.post("/users/")
def create_user(user: User):
return {"user": user}Параметры Field:
| Параметр | Назначение |
|---|---|
min_length | Минимальная длина |
max_length | Максимальная длина |
ge | Больше или равно |
le | Меньше или равно |
regex | Регулярное выражение |
default | Значение по умолчанию |
Валидация через валидаторы
from pydantic import BaseModel, validator
class User(BaseModel):
name: str
password: str
@validator('password')
def validate_password(cls, value):
if len(value) < 6:
raise ValueError('Пароль должен быть не менее 6 символов')
return valueПолный пример
from fastapi import FastAPI
from pydantic import BaseModel, Field
from typing import Optional, List
app = FastAPI()
class Address(BaseModel):
street: str
city: str
zip_code: str
class UserCreate(BaseModel):
name: str = Field(..., min_length=2, max_length=50)
age: int = Field(..., ge=0, le=120)
email: str = Field(..., regex=r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
phone: Optional[str] = None
address: Optional[Address] = None
tags: List[str] = []
@app.post("/users/")
def create_user(user: UserCreate):
return {
"message": "Пользователь создан",
"user": user
}
@app.post("/users/bulk/")
def create_users(users: List[UserCreate]):
return {"message": f"Создано {len(users)} пользователей"}Задачи для закрепления
Задача 1. Создай модель Product с полями: name, price, description.
Задача 2. Добавь валидацию: price >= 0.
Задача 3. Создай модель Order с вложенной моделью Product.
Задача 4. Создай эндпоинт для создания заказа.
Задача 5. Добавь опциональное поле discount в модель Product.
Ответы:
Задача 1.
class Product(BaseModel):
name: str
price: float
description: Optional[str] = NoneЗадача 2.
class Product(BaseModel):
name: str
price: float = Field(..., ge=0)
description: Optional[str] = NoneЗадача 3.
class Product(BaseModel):
name: str
price: float
class Order(BaseModel):
id: int
products: List[Product]Задача 4.
@app.post("/orders/")
def create_order(order: Order):
return {"order": order}Задача 5.
class Product(BaseModel):
name: str
price: float
discount: Optional[float] = 0.0Нюансы и подводные камни
- Pydantic модели автоматически валидируют данные при получении.
- Ошибки валидации возвращают статус 422.
Fieldпозволяет добавлять дополнительные проверки (min_length, ge, le, regex).- Можно создавать вложенные модели и списки моделей.
- Валидаторы (
@validator) выполняются в порядке объявления полей. - Pydantic автоматически преобразует типы (например, строку в число).
OptionalсNoneделает поле необязательным.
Частые ошибки и как их избежать
Ошибка 1: Забыл импортировать Field
from pydantic import BaseModel, Field
Ошибка 2: Неправильная валидация вложенных моделей
Проверяй вложенные модели отдельно.
Ошибка 3: Использование @validator без values для кросс-полей
Для проверки нескольких полей используй values в валидаторе.
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Модель | class User(BaseModel): |
| Обязательное поле | name: str |
| Опциональное поле | age: Optional[int] = None |
| Вложенная модель | address: Address |
| Список | items: List[str] |
| Валидация | Field(..., min_length=2) |
| Валидатор | @validator('field') |
Заключение
Сегодня мы:
- Узнали, что такое Pydantic модели
- Научились создавать модели
- Добавили валидацию
- Использовали вложенные модели








