Pydantic 基础 #
什么是 Pydantic? #
Pydantic 是一个使用 Python 类型注解进行数据验证和设置管理的库。它是 FastAPI 的核心依赖之一。
text
┌─────────────────────────────────────────────────────────────┐
│ Pydantic 的作用 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入数据 ────> Pydantic 模型 ────> 验证后的数据 │
│ │
│ 功能: │
│ ✅ 数据验证 │
│ ✅ 类型转换 │
│ ✅ 序列化/反序列化 │
│ ✅ JSON Schema 生成 │
│ ✅ 设置管理 │
│ │
└─────────────────────────────────────────────────────────────┘
安装 #
bash
pip install pydantic
基本模型 #
定义模型 #
python
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
age: int | None = None
创建实例 #
python
user = User(id=1, name='John', email='john@example.com')
print(user)
# id=1 name='John' email='john@example.com' age=None
user = User(id=1, name='John', email='john@example.com', age=30)
print(user)
# id=1 name='John' email='john@example.com' age=30
从字典创建 #
python
user_data = {
'id': 1,
'name': 'John',
'email': 'john@example.com'
}
user = User(**user_data)
类型转换 #
python
user = User(id='1', name='John', email='john@example.com')
print(user.id) # 1 (自动转换为 int)
print(type(user.id)) # <class 'int'>
字段类型 #
基本类型 #
python
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
quantity: int
is_active: bool
可选类型 #
python
from typing import Optional
class User(BaseModel):
name: str
age: Optional[int] = None
# 或 Python 3.10+ 语法
age: int | None = None
集合类型 #
python
from typing import List, Dict, Set, Tuple
class Data(BaseModel):
items: list[str] # 字符串列表
mapping: dict[str, int] # 字典
unique: set[int] # 集合
coordinates: tuple[int, int] # 元组
复杂类型 #
python
from typing import List, Dict, Any
class Complex(BaseModel):
list_of_dicts: List[Dict[str, Any]]
nested: Dict[str, List[int]]
any_value: Any
特殊类型 #
日期时间 #
python
from datetime import datetime, date, time, timedelta
from pydantic import BaseModel
class Event(BaseModel):
created_at: datetime
event_date: date
start_time: time
duration: timedelta
event = Event(
created_at='2024-01-15T10:30:00',
event_date='2024-01-20',
start_time='14:00:00',
duration='1:30:00'
)
URL 和 Email #
python
from pydantic import BaseModel, HttpUrl, EmailStr
class Contact(BaseModel):
email: EmailStr
website: HttpUrl
contact = Contact(
email='user@example.com',
website='https://example.com'
)
UUID #
python
from uuid import UUID
from pydantic import BaseModel
class Resource(BaseModel):
id: UUID
resource = Resource(id='123e4567-e89b-12d3-a456-426614174000')
枚举 #
python
from enum import Enum
from pydantic import BaseModel
class Status(str, Enum):
pending = 'pending'
approved = 'approved'
rejected = 'rejected'
class Item(BaseModel):
status: Status
item = Item(status='pending')
print(item.status) # Status.pending
Field 函数 #
基本用法 #
python
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(..., description='Item name')
price: float = Field(..., gt=0, description='Item price')
quantity: int = Field(default=0, ge=0)
字段约束 #
python
class Product(BaseModel):
name: str = Field(
...,
min_length=2,
max_length=50,
description='Product name'
)
price: float = Field(
...,
gt=0,
le=10000,
description='Price in dollars'
)
discount: float = Field(
default=0,
ge=0,
le=1,
description='Discount rate (0-1)'
)
quantity: int = Field(
default=0,
ge=0,
description='Stock quantity'
)
默认值 #
python
from datetime import datetime
class Order(BaseModel):
created_at: datetime = Field(default_factory=datetime.now)
items: list[str] = Field(default_factory=list)
别名 #
python
class User(BaseModel):
username: str = Field(..., alias='user_name')
email: str = Field(..., alias='email_address')
user = User(user_name='john', email_address='john@example.com')
print(user.username) # john
示例 #
python
class Item(BaseModel):
name: str = Field(..., examples=['iPhone 15'])
price: float = Field(..., examples=[999.99])
验证器 #
field_validator #
python
from pydantic import BaseModel, field_validator
class User(BaseModel):
name: str
username: str
@field_validator('username')
@classmethod
def username_alphanumeric(cls, v: str) -> str:
if not v.isalnum():
raise ValueError('must be alphanumeric')
return v.lower()
多字段验证器 #
python
class User(BaseModel):
username: str
email: str
@field_validator('username', 'email')
@classmethod
def lowercase(cls, v: str) -> str:
return v.lower()
model_validator #
python
from pydantic import BaseModel, model_validator
class User(BaseModel):
password: str
confirm_password: str
@model_validator(mode='after')
def passwords_match(self):
if self.password != self.confirm_password:
raise ValueError('passwords do not match')
return self
验证前后处理 #
python
class Item(BaseModel):
name: str
price: float
@field_validator('name')
@classmethod
def strip_name(cls, v: str) -> str:
return v.strip()
@field_validator('price')
@classmethod
def round_price(cls, v: float) -> float:
return round(v, 2)
模型方法 #
model_dump #
python
user = User(id=1, name='John', email='john@example.com')
user_dict = user.model_dump()
# {'id': 1, 'name': 'John', 'email': 'john@example.com'}
user_dict = user.model_dump(exclude={'email'})
# {'id': 1, 'name': 'John'}
user_dict = user.model_dump(include={'id', 'name'})
# {'id': 1, 'name': 'John'}
model_dump_json #
python
user_json = user.model_dump_json()
# '{"id":1,"name":"John","email":"john@example.com"}'
model_validate #
python
user = User.model_validate({'id': 1, 'name': 'John', 'email': 'john@example.com'})
model_validate_json #
python
user = User.model_validate_json('{"id":1,"name":"John","email":"john@example.com"}')
模型配置 #
ConfigDict #
python
from pydantic import BaseModel, ConfigDict
class Item(BaseModel):
model_config = ConfigDict(
str_strip_whitespace=True,
validate_assignment=True,
extra='forbid'
)
name: str
price: float
常用配置 #
text
┌─────────────────────────────────────────────────────────────┐
│ 模型配置选项 │
├─────────────────────────────────────────────────────────────┤
│ │
│ str_strip_whitespace 自动去除字符串空白 │
│ str_to_lower 自动转小写 │
│ str_to_upper 自动转大写 │
│ validate_assignment 赋值时验证 │
│ extra 额外字段处理 │
│ 'ignore' 忽略 │
│ 'forbid' 禁止(报错) │
│ 'allow' 允许 │
│ populate_by_name 允许通过字段名填充 │
│ from_attributes 从对象属性读取 │
│ use_enum_values 使用枚举值而非枚举对象 │
│ │
└─────────────────────────────────────────────────────────────┘
配置示例 #
python
class User(BaseModel):
model_config = ConfigDict(
str_strip_whitespace=True,
validate_assignment=True,
extra='forbid'
)
name: str
email: str
user = User(name=' John ', email='john@example.com')
print(user.name) # 'John' (已去除空白)
user.name = ' Jane '
print(user.name) # 'Jane' (赋值时也验证)
嵌套模型 #
简单嵌套 #
python
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
name: str
address: Address
user = User(
name='John',
address={
'street': '123 Main St',
'city': 'New York',
'country': 'USA'
}
)
列表嵌套 #
python
class Item(BaseModel):
name: str
price: float
class Order(BaseModel):
items: list[Item]
total: float
order = Order(
items=[
{'name': 'Item 1', 'price': 10.0},
{'name': 'Item 2', 'price': 20.0}
],
total=30.0
)
继承 #
模型继承 #
python
class UserBase(BaseModel):
email: str
full_name: str | None = None
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool = True
class UserInDB(User):
hashed_password: str
完整示例 #
python
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field, EmailStr, field_validator, ConfigDict
class Address(BaseModel):
street: str = Field(..., min_length=5)
city: str = Field(..., min_length=2)
country: str = Field(..., min_length=2)
postal_code: str = Field(..., pattern=r'^\d{5}$')
class UserBase(BaseModel):
model_config = ConfigDict(
str_strip_whitespace=True,
validate_assignment=True
)
username: str = Field(
...,
min_length=3,
max_length=20,
pattern='^[a-zA-Z0-9_]+$'
)
email: EmailStr
full_name: Optional[str] = Field(None, min_length=2)
@field_validator('username')
@classmethod
def username_lowercase(cls, v: str) -> str:
return v.lower()
class UserCreate(UserBase):
password: str = Field(..., min_length=8)
confirm_password: str
@field_validator('confirm_password')
@classmethod
def passwords_match(cls, v: str, info) -> str:
if 'password' in info.data and v != info.data['password']:
raise ValueError('passwords do not match')
return v
class User(UserBase):
id: int
address: Optional[Address] = None
created_at: datetime = Field(default_factory=datetime.now)
is_active: bool = True
class UserInDB(User):
hashed_password: str
下一步 #
现在你已经掌握了 Pydantic 基础,接下来学习 依赖注入,了解 FastAPI 强大的依赖系统!
最后更新:2026-03-29