JavaRush /Курсы /Модуль 4: FastAPI /Создание Pydantic-моделей для валидации данных

Создание Pydantic-моделей для валидации данных

Модуль 4: FastAPI
3 уровень , 1 лекция
Открыта

Теперь мы готовимся идти дальше и научимся создавать 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 для:

  1. Валидации данных в запросах (например, обрабатывая API-эндпоинт в FastAPI).
  2. Валидации данных перед сохранением их в базе данных.
  3. Генерации документации для вашего API (спасибо интеграции с FastAPI).

В следующей лекции мы посмотрим, как встраивать эти модели в эндпоинты FastAPI. А пока, попробуйте создать свою модель и поэкспериментируйте с обработкой данных. Увидите, насколько всё это удобно.

1
Задача
Модуль 4: FastAPI, 3 уровень, 1 лекция
Недоступна
Создание базовой модели пользователя
Создание базовой модели пользователя
1
Задача
Модуль 4: FastAPI, 3 уровень, 1 лекция
Недоступна
Модель продуктов
Модель продуктов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ