JavaRush /Курсы /Модуль 4: FastAPI /Использование Field для настройки полей моделей

Использование Field для настройки полей моделей

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

В FastAPI на базе Pydantic Field позволяет задавать дополнительные настройки для полей моделей. Это поднимает валидацию данных на новую высоту. С помощью Field можно:

  • Настраивать значения по умолчанию для полей.
  • Ограничивать возможные значения (например, минимальная длина строки, диапазон чисел).
  • Добавлять метаданные (описания, примеры).
  • Указывать дополнительные условия валидации.

Если задуматься, то Field — это как чек-лист правил для каждого поля. У каждого программиста есть своя вариация "что проверить перед сдачей проекта", так и у нашего API есть строгая проверка данных через Field.

Простая аналогия: если бы наши данные были гостем на вечеринке, то Field — это строгий дядя-секьюрити, который проверяет, одет ли гость в приличную одежду, есть ли у него приглашение и, конечно, не слишком ли громкий у него смех.


Синтаксис Field

Чтобы использовать Field, просто импортируем его из pydantic и добавляем в описание модели:


from pydantic import BaseModel, Field

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, description="Имя пользователя")
    age: int = Field(..., ge=18, le=150, description="Возраст пользователя (должен быть от 18 до 150)")

Разберём параметры:

  • ... (Ellipsis) означает, что поле обязательно.
  • min_length и max_length задают минимальную и максимальную длину строки.
  • ge (greater or equal) и le (less or equal) задают диапазон значений для числа.
  • description добавляет описание для документации.

Как использовать Field в реальных проектах?

Давайте создадим модель для регистрации пользователей. Параметры должны валидироваться следующим образом:

  1. Имя пользователя (username) — должно быть обязательным, длина от 3 до 50 символов.
  2. Электронная почта (email) — строка, которая обязательно должна быть валидным email.
  3. Возраст (age) — обязателен, от 18 до 120 лет.
  4. Описание (bio) — необязательное поле, не длиннее 300 символов.

Пример кода:


from pydantic import BaseModel, Field, EmailStr

class RegisterUser(BaseModel):
    username: str = Field(..., min_length=3, max_length=50, description="Имя пользователя")
    email: EmailStr = Field(..., description="Электронная почта пользователя")
    age: int = Field(..., ge=18, le=120, description="Возраст пользователя")
    bio: str = Field(None, max_length=300, description="Краткое описание о пользователе")

# Пример использования:
input_data = {
    "username": "JohnDoe",
    "email": "john.doe@example.com",
    "age": 25,
    "bio": "I love Python and FastAPI!"
}

user = RegisterUser(**input_data)
print(user)

Что происходит при валидации?

Если данные соответствуют требованиям, Pydantic создаёт объект модели на основе входных данных. Если какой-то параметр не проходит проверку, будет выброшено исключение ValidationError с подробным описанием, что пошло не так.

Например, если передать в age отрицательное значение:


input_data = {
    "username": "JohnDoe",
    "email": "john.doe@example.com",
    "age": -5,  # Это явно не ок!
    "bio": "I love Python and FastAPI!"
}

try:
    user = RegisterUser(**input_data)
except ValidationError as e:
    print(e.json())

Получим:


[
  {
    "loc": ["age"],
    "msg": "ensure this value is greater than or equal to 18",
    "type": "value_error.number.not_ge",
    "ctx": {"limit_value": 18}
  }
]

Настройка значений по умолчанию

Если поле не обязательно, можно указать значение по умолчанию, которое автоматически подставится при отсутствии данных:


class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    age: int = Field(30, ge=18, le=120)  # Значение по умолчанию — 30
    bio: str = Field("No bio provided.", max_length=300)  # Дефолтное описание

# Пример:
input_data = {
    "username": "JaneDoe"
}

user = User(**input_data)
print(user)
# Вывод: username='JaneDoe' age=30 bio='No bio provided.'

Описание полей для OpenAPI документации

FastAPI автоматически использует описания, указанные в Field, чтобы дополнить документацию. Если открыть автоматически сгенерированную Swagger UI, можно увидеть красивые описания всех полей:


from fastapi import FastAPI

app = FastAPI()

@app.post("/users/")
async def create_user(user: RegisterUser):
    return user

Теперь, зайдя на /docs, вы увидите каждое наше описание, примеры и ограничения. Презентабельно и профессионально!


Дополнительные параметры

  1. alias — задаёт альтернативное название поля (например, для совместимости с внешними API).
  2. example — задаёт пример значения (отображается в Swagger UI).
  3. regex — позволяет указать регулярное выражение для проверки данных.

Пример использования alias и regex:

Попробуем создать модель, которая валидирует телефонные номера:


class PhoneNumber(BaseModel):
    phone: str = Field(..., regex=r"^\+\d{1,3}-\d{3}-\d{4}$", alias="phone_number", example="+123-456-7890")

# Пример:
input_data = {"phone_number": "+123-456-7890"}
phone = PhoneNumber(**input_data)
print(phone)

Модель проверит, что телефонный номер соответствует формату +XXX-XXX-XXXX. Если строка не соответствует регулярному выражению, будет выдана ошибка.


Типичные ошибки при работе с Field

Иногда разработчики сталкиваются с такими проблемами:

  1. Ошибка с обязательными полями. Если забыть указать значение для обязательного поля (с ...), Pydantic бросит ValidationError.
  2. Неверные типы данных. Если передать строку вместо числа или наоборот, произойдёт ошибка валидации. Pydantic проверяет типы данных с особой строгостью.
  3. Игнорирование метаданных. Некоторые новички не указывают описания, примеры или удобные ограничения, что затрудняет поддержку кода в будущем.

Практическая задача

Давайте напишем модель для добавления товаров в интернет-магазин. У товара должно быть:

  • Название (name), обязательное, до 100 символов.
  • Цена (price), обязательное поле, положительное число.
  • Категория (category), строка, значение по умолчанию — "general".
  • Описание (description), необязательное поле, не более 500 символов.

Реализуйте эндпоинт /products/, который принимает эту модель и возвращает сохранённые данные.

Решение:


from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()

class Product(BaseModel):
    name: str = Field(..., max_length=100, description="Название товара")
    price: float = Field(..., gt=0, description="Цена товара (должна быть положительной)")
    category: str = Field("general", description="Категория товара")
    description: str = Field(None, max_length=500, description="Описание товара")

@app.post("/products/")
async def create_product(product: Product):
    return {"msg": "Товар успешно добавлен!", "product": product}

Итак, теперь вы можете настраивать поля в ваших моделях как профессионал. Ваш код стал не только надёжнее, но и элегантнее. Мы продолжаем! 😉

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

# Pydantic v2 современный подход для валидации 
age: Annotated[int, Field(ge=0)] = 0

# Устаревший подход
age: int = Field(0, ge=0)