Преобразование моделей в dict и JSON, режимы include/exclude, by_alias, exclude_none.
Сериализация — это искусство превращать модели в данные для передачи вовне
from pydantic import BaseModel
from datetime import datetime
class User(BaseModel):
id: int
name: str
email: str
created_at: datetime
user = User(
id=1,
name="Alice",
email="alice@example.com",
created_at=datetime(2026, 3, 18, 10, 30)
)
# Преобразование в dict
data = user.model_dump()
# {'id': 1, 'name': 'Alice', 'email': 'alice@example.com',
# 'created_at': datetime.datetime(2026, 3, 18, 10, 30)}# Преобразование в JSON-строку
json_str = user.model_dump_json()
# '{"id":1,"name":"Alice","email":"alice@example.com","created_at":"2026-03-18T10:30:00"}'
# С форматированием
json_str = user.model_dump_json(indent=2)# Только указанные поля
data = user.model_dump(include={'name', 'email'})
# {'name': 'Alice', 'email': 'alice@example.com'}
# С вложенными моделями
class Order(BaseModel):
id: int
user: User
items: list[str]
order = Order(id=1, user=user, items=["item1", "item2"])
# Включить только name из user
data = order.model_dump(include={'id', 'user': {'name'}})
# {'id': 1, 'user': {'name': 'Alice'}}# Исключить поля
data = user.model_dump(exclude={'created_at'})
# {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'}
# Исключить вложенные поля
data = order.model_dump(exclude={'user': {'email'}})
# user без emailclass User(BaseModel):
user_name: str = Field(alias="userName")
user_id: int = Field(alias="userId")
user = User(userName="Alice", userId=1)
# По умолчанию (имена полей)
data = user.model_dump()
# {'user_name': 'Alice', 'user_id': 1}
# С алиасами
data = user.model_dump(by_alias=True)
# {'userName': 'Alice', 'userId': 1}class User(BaseModel):
name: str
email: str | None = None
phone: str | None = None
user = User(name="Alice", email=None)
# По умолчанию
data = user.model_dump()
# {'name': 'Alice', 'email': None, 'phone': None}
# Без None
data = user.model_dump(exclude_none=True)
# {'name': 'Alice'}class User(BaseModel):
name: str
is_active: bool = True
role: str = "user"
user = User(name="Alice")
# Без значений по умолчанию
data = user.model_dump(exclude_defaults=True)
# {'name': 'Alice'}
# Со значениями по умолчанию
data = user.model_dump()
# {'name': 'Alice', 'is_active': True, 'role': 'user'}from datetime import datetime
class Event(BaseModel):
date: datetime
event = Event(date=datetime(2026, 3, 18, 10, 30))
# mode='python' (по умолчанию)
data = event.model_dump(mode='python')
# {'date': datetime.datetime(2026, 3, 18, 10, 30)} # datetime-объект
# mode='json'
data = event.model_dump(mode='json')
# {'date': '2026-03-18T10:30:00'} # ISO-строкаclass Data(BaseModel):
value: float
data = Data(value=1.123456789)
# Обычная сериализация
json_str = data.model_dump_json()
# '{"value":1.123456789}'
# С round_trip (для точного восстановления)
json_str = data.model_dump_json(round_trip=True)
# '{"value":1.123456789}' # может использовать больше знаковclass Address(BaseModel):
street: str
city: str
class User(BaseModel):
name: str
address: Address
user = User(
name="Alice",
address=Address(street="123 Main St", city="NYC")
)
# Полная сериализация
data = user.model_dump()
# {'name': 'Alice', 'address': {'street': '123 Main St', 'city': 'NYC'}}
# Исключение вложенных полей
data = user.model_dump(exclude={'address': {'street'}})
# {'name': 'Alice', 'address': {'city': 'NYC'}}class Item(BaseModel):
name: str
price: float
class Order(BaseModel):
items: list[Item]
order = Order(items=[
Item(name="Mouse", price=29.99),
Item(name="Keyboard", price=79.99)
])
# Сериализация списка моделей
data = order.model_dump()
# {'items': [{'name': 'Mouse', 'price': 29.99}, ...]}class UserResponse(BaseModel):
id: int
name: str
email: str
password_hash: str # не должен попасть в ответ
created_at: datetime
model_config = ConfigDict(extra='forbid')
def get_user_response(user: UserResponse) -> dict:
return user.model_dump(
exclude={'password_hash'},
exclude_none=True,
by_alias=True
)class Config(BaseModel):
database_url: str
api_key: str
debug: bool = False
config = Config(database_url="postgres://...", api_key="secret")
# Логирование без секретов
log_data = config.model_dump(exclude={'api_key'})
logger.info(f"Config: {log_data}")import json
# Сохранение
data = user.model_dump_json()
with open("user.json", "w") as f:
f.write(data)
# Восстановление
with open("user.json") as f:
data = f.read()
user = User.model_validate_json(data)Создайте модели для API ответов:
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional, Generic, TypeVar
T = TypeVar('T')
class User(BaseModel):
id: int
username: str
email: str
password_hash: str # скрыть при сериализации
created_at: datetime
updated_at: Optional[datetime] = None
# Создайте классы:
# 1. UserPublic — публичная версия User (без password_hash)
# 2. UserCreate — для создания (все поля кроме id, created_at, updated_at)
# 3. UserUpdate — для обновления (все поля optional)
# 4. APIResponse[T] — обёртка для ответов API
# Пример использования:
# response = APIResponse(data=user_public, status="success")
# json_response = response.model_dump_json(exclude_none=True)В следующей теме изучим вычисляемые поля через @computed_field.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.