Теперь мы готовимся идти дальше и научимся создавать Pydantic-модели для валидации данных. Без паники: с практикой и немного фантазии, вы сделаете это с закрытыми глазами (но лучше держать их открытыми, потому что ошибки в коде видеть лучше).
Если взглянуть на приложения, которые вы писали ранее, согласитесь, валидация данных — это тот ещё челлендж. Если вы проверяете типы данных и условия вручную, это как собирать мебель из IKEA без инструкции. Вот тут-то на сцену выходит Pydantic. С его помощью вы можете:
- Упростить обработку данных.
- Избежать "плохих" данных в запросах.
- Сделать своё API более устойчивым (и впечатлить собеседника на интервью).
1. Основы создания модели: знакомство с BaseModel
В Pydantic, любой набор данных начинается с класса, который наследуется от pydantic.BaseModel. Почему мы наследуемся от BaseModel? Это как покупка собрано-готового конструктора: он сам всё проверит, преобразует, и выдаст вам корректный набор данных.
Вот базовый пример:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
email: str
Здесь мы определили класс User с тремя полями:
name: строка (обязательно).age: целое число (обязательно).email: строка (обязательно).
Теперь мы можем использовать эту модель для валидации входных данных.
input_data = {
"name": "Иван",
"age": 30,
"email": "ivan@example.com"
}
user = User(**input_data)
print(user) # User(name='Иван', age=30, email='ivan@example.com')
Если данные не подходят по типу, Pydantic бросит понятное исключение. Например:
bad_data = {
"name": "Иван",
"age": "тридцать", # Упс, возраст должен быть числом
"email": "ivan@example.com"
}
user = User(**bad_data)
# ValidationError: value is not a valid integer
2. Дополнительные возможности Pydantic: автоматическое преобразование
Pydantic — словно заботливый бариста. Если ему принесли полуготовый заказ, он попытается "доделать". Например, Pydantic способен автоматически преобразовать типы данных. Это работает, если передаваемые данные хотя бы похожи на нужные.
data = {
"name": "Мария",
"age": "25", # Строка, но выглядит как число
"email": "maria@example.com"
}
user = User(**data)
print(user)
# User(name='Мария', age=25, email='maria@example.com')
Однако, это не значит, что можно расслабиться и запихивать любые данные! Если преобразование невозможно, ошибка всё равно всплывёт.
3. Поля модели: как задать конкретные типы данных
Pydantic поддерживает множество типов данных: от строковых до сложных коллекций. Вот небольшой справочник:
| Тип данных в Pydantic | Пример использования |
|---|---|
str |
name: str |
int |
age: int |
float |
price: float |
bool |
is_active: bool |
datetime |
created_at: datetime |
list |
tags: list[str] |
dict |
metadata: dict[str, str] |
Пример чуть сложнее:
from pydantic import BaseModel
from datetime import datetime
class Product(BaseModel):
name: str
price: float
is_active: bool
tags: list[str]
created_at: datetime
data = {
"name": "Лаптоп",
"price": 799.99,
"is_active": True,
"tags": ["электроника", "компьютеры"],
"created_at": "2023-10-16T12:00:00"
}
product = Product(**data)
print(product)
# Product(name='Лаптоп', price=799.99, is_active=True, tags=['электроника', 'компьютеры'], created_at=datetime.datetime(2023, 10, 16, 12, 0))
Обратите внимание на поле created_at: строка ISO-8601 преобразована в datetime автоматически.
4. Пример создания базовой модели: пользовательский профиль
Давайте шаг за шагом создадим модель для валидации данных пользователя. Она будет включать следующие поля:
username: строка, обязательное поле.email: строка, обязательное поле.bio: строка, необязательное поле.birth_date: дата, необязательное поле.
Создаём модель:
from pydantic import BaseModel
class UserProfile(BaseModel):
username: str
email: str
bio: str | None = None # Поле может быть необязательным
birth_date: datetime.date | None = None
Пример использования:
data = {
"username": "super_coder",
"email": "coder@example.com",
"bio": "Люблю кодить в Pydantic!",
"birth_date": "1990-05-13"
}
user = UserProfile(**data)
print(user)
# UserProfile(username='super_coder', email='coder@example.com', bio='Люблю кодить в Pydantic!', birth_date=datetime.date(1990, 5, 13))
5. Обработка ошибок: что происходит при неправильных данных
Ошибки в Pydantic — это отдельное искусство. Вот что произойдёт, если передать некорректные данные:
broken_data = {
"username": "no_email_user",
"email": "неправильный_email"
}
user = UserProfile(**broken_data)
# ValidationError: value is not a valid email address
Огромный плюс Pydantic в том, что ошибки всегда содержат детальное объяснение проблемы.
6. Итог: как применять Pydantic-модели в реальных проектах?
Вы можете использовать Pydantic для:
- Валидации данных в запросах (например, обрабатывая API-эндпоинт в FastAPI).
- Валидации данных перед сохранением их в базе данных.
- Генерации документации для вашего API (спасибо интеграции с FastAPI).
В следующей лекции мы посмотрим, как встраивать эти модели в эндпоинты FastAPI. А пока, попробуйте создать свою модель и поэкспериментируйте с обработкой данных. Увидите, насколько всё это удобно.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ