💻 Примеры кода

🎯 Практика: модели Pydantic, валидация, JSON

Пример 1. Простая модель

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    age: int
    is_active: bool = True

user = User(id=1, name="Anna", age=25)
print(user)
# id=1 name='Anna' age=25 is_active=True

# Ошибка типа
# User(id="not_a_number", name="Anna", age=25)
# → ValidationError: id must be a valid integer

Пример 2. Вложенные модели

from pydantic import BaseModel

class Address(BaseModel):
    city: str
    street: str
    house_number: int

class User(BaseModel):
    id: int
    name: str
    age: int
    address: Address

addr = Address(city="Berlin", street="Main St", house_number=42)
user = User(id=1, name="John", age=30, address=addr)
print(user.address.city)  # Berlin

Пример 3. JSON ↔ Pydantic

from pydantic import BaseModel, ValidationError

class User(BaseModel):
    name: str
    age: int

json_string = '{"name": "Alice", "age": 28}'

# JSON → модель
try:
    user = User.model_validate_json(json_string, strict=True)
    print(user)  # name='Alice' age=28
except ValidationError as e:
    print("Ошибка:", e)

# Модель → JSON
output = user.model_dump_json()
print(output)  # {"name":"Alice","age":28}

Пример 4. Наследование моделей

from pydantic import BaseModel, EmailStr

class User(BaseModel):
    name: str
    email: EmailStr

class AdminUser(User):
    is_superuser: bool
    access_level: int = 10

admin = AdminUser(name="Boss", email="boss@example.com", is_superuser=True)
print(admin)
# name='Boss' email='boss@example.com' is_superuser=True access_level=10

Пример 5. Field с ограничениями

from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(..., min_length=2, max_length=100)
    price: float = Field(gt=0, description="Цена больше нуля")
    quantity: int = Field(ge=0, le=1000)

product = Product(name="Laptop", price=999.99, quantity=5)
print(product.model_dump_json())

Пример 6. Кастомный валидатор

from pydantic import BaseModel, field_validator, EmailStr

class User(BaseModel):
    name: str
    age: int
    email: EmailStr

    @field_validator('name')
    def name_must_be_alpha(cls, value: str) -> str:
        if not value.isalpha():
            raise ValueError('Имя должно содержать только буквы')
        return value

    @field_validator('email')
    def email_must_be_com(cls, value: str) -> str:
        if not value.endswith('.com'):
            raise ValueError('Email должен заканчиваться на .com')
        return value

user = User(name="Alice", age=30, email="alice@example.com")
print(user)

Пример 7. Валидация нескольких полей

from pydantic import BaseModel, model_validator

class Employee(BaseModel):
    age: int
    is_employed: bool

    @model_validator(mode='after')
    def check_age_for_employed(self):
        if self.is_employed and not (18 <= self.age <= 65):
            raise ValueError('Если занят, возраст должен быть от 18 до 65')
        return self

# Успешно
emp = Employee(age=30, is_employed=True)

# Ошибка
# Employee(age=70, is_employed=True)
# → ValueError: Если занят, возраст должен быть от 18 до 65

Пример 8. model_config и кастомный сериализатор поля

from datetime import datetime
from pydantic import BaseModel, ConfigDict, field_serializer

class Event(BaseModel):
    model_config = ConfigDict(
        str_strip_whitespace=True,
        str_min_length=1,
    )

    title: str
    created_at: datetime

    @field_serializer("created_at")
    def serialize_created_at(self, v: datetime) -> str:
        return v.strftime("%d.%m.%Y %H:%M")

event = Event(title="  Meetup  ", created_at=datetime.now())
print(event.title)  # "Meetup" (пробелы обрезаны)
print(event.model_dump_json())
# {"title":"Meetup","created_at":"08.06.2026 22:16"}