Использование Field для ограничения значений, gt, lt, min_length, regex и другие встроенные валидаторы.
Field — это декларативный способ описать ограничения данных без написания кода валидации
Field позволяет настроить поле модели:
from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(
min_length=3,
max_length=20,
description="Имя пользователя (3-20 символов)",
examples=["alice", "bob123"]
)
age: int = Field(
ge=0,
le=150,
description="Возраст в годах",
default=18
)Параметры Field:
default / default_factory — значение по умолчаниюdescription — описание поля (для документации)examples — примеры значенийalias — альтернативное имя для сериализацииtitle — заголовок поляclass Product(BaseModel):
# Длина строки
name: str = Field(min_length=2, max_length=100)
description: str = Field(max_length=1000)
# Regex-паттерн
sku: str = Field(pattern=r'^[A-Z]{3}-\d{4}$') # ABC-1234
email: str = Field(pattern=r'^.+@.+\..+$')
# Только для строк
title: str = Field(min_length=1, strip_whitespace=True)strip_whitespace удаляет пробелы по краям:
product = Product(
name=" Widget ", # станет "Widget"
sku="ABC-1234",
email="test@example.com"
)
print(product.name) # "Widget" (без пробелов)class Order(BaseModel):
# Больше чем
quantity: int = Field(gt=0) # > 0
# Больше или равно
min_price: float = Field(ge=0) # >= 0
# Меньше чем
discount: float = Field(lt=1) # < 1
# Меньше или равно
max_items: int = Field(le=100) # <= 100
# Диапазон
rating: float = Field(ge=0, le=5) # 0-5
# Кратность
batch_size: int = Field(multiple_of=10) # кратно 10Пример:
# OK
order = Order(
quantity=5,
min_price=0,
discount=0.1,
max_items=100,
rating=4.5,
batch_size=20
)
# Ошибка: quantity должен быть > 0
Order(quantity=0, min_price=0, discount=0.1, max_items=100, rating=4.5, batch_size=20)
# ValidationError: Input should be greater than 0from typing import List, Dict, Set
class Data(BaseModel):
# Список с ограничениями
tags: list[str] = Field(min_length=1, max_length=10)
# Множество
unique_ids: set[int] = Field(min_length=1)
# Словарь
metadata: dict[str, str] = Field(min_length=1)
# Вложенные ограничения
matrix: list[list[int]] = Field(min_length=1)Когда значение по умолчанию должно вычисляться:
from datetime import datetime, timedelta
from uuid import uuid4
class Event(BaseModel):
# UUID для каждого экземпляра
id: str = Field(default_factory=lambda: str(uuid4()))
# Текущее время
created_at: datetime = Field(default_factory=datetime.now)
# Время через час
expires_at: datetime = Field(
default_factory=lambda: datetime.now() + timedelta(hours=1)
)
# Пустой список (вместо mutable default)
tags: list[str] = Field(default_factory=list)Важно: используйте default_factory для изменяемых типов (list, dict, set)!
# НЕПРАВИЛЬНО: mutable default
class Wrong(BaseModel):
items: list[str] = [] # общий список для всех экземпляров!
# ПРАВИЛЬНО
class Right(BaseModel):
items: list[str] = Field(default_factory=list)class User(BaseModel):
user_name: str = Field(alias="userName")
user_id: int = Field(alias="userId")
# Создание с alias
user = User(userName="Alice", userId=1)
print(user.user_name) # "Alice"
# Сериализация с alias
data = user.model_dump(by_alias=True)
print(data) # {'userName': 'Alice', 'userId': 1}from pydantic import ConfigDict
class User(BaseModel):
model_config = ConfigDict(populate_by_name=True)
user_name: str = Field(alias="userName")
# Работают оба варианта
user1 = User(userName="Alice") # через alias
user2 = User(user_name="Bob") # через имя поляField добавляет метаданные для генерации JSON Schema:
class Product(BaseModel):
name: str = Field(
description="Название товара",
examples=["Wireless Mouse", "Mechanical Keyboard"],
min_length=2,
max_length=100
)
price: float = Field(
description="Цена в долларах",
gt=0,
examples=[19.99, 29.99]
)
# Генерация схемы
schema = Product.model_json_schema()
print(schema['properties']['name'])
# {
# 'description': 'Название товара',
# 'examples': ['Wireless Mouse', 'Mechanical Keyboard'],
# 'maxLength': 100,
# 'minLength': 2,
# 'title': 'Name',
# 'type': 'string'
# }Современный способ через typing.Annotated:
from typing import Annotated
class User(BaseModel):
username: Annotated[
str,
Field(min_length=3, max_length=20),
Field(description="Имя пользователя"),
Field(pattern=r'^[a-zA-Z0-9_]+$')
]
# Или всё в одном Field
email: Annotated[
str,
Field(pattern=r'^.+@.+\..+$', description="Email")
]Можно комбинировать несколько Field, но обычно достаточно одного:
username: Annotated[str, Field(min_length=3, max_length=20, pattern=r'^[a-z]+$')]Создайте модель UserProfile с полной валидацией:
from pydantic import BaseModel, Field, EmailStr
from typing import Optional, List
from datetime import datetime
class UserProfile(BaseModel):
# username: 3-20 символов, только буквы/цифры/подчёркивание
# email: валидный email
# age: 0-150, необязательное
# bio: до 500 символов, необязательное
# website: необязательный URL
# phone: формат +1234567890 (regex)
# tags: список строк, 0-10 тегов
# created_at: datetime, по умолчанию сейчас
# github_username: необязательное, алиас "githubUsername"
pass
# Пример:
profile = UserProfile(
username="alice_dev",
email="alice@example.com",
age=25,
bio="Python developer",
phone="+1234567890",
tags=["python", "backend"],
githubUsername="alicedev"
)Проверьте валидацию:
В следующей теме изучим кастомные валидаторы через @field_validator и @model_validator.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.