上一章中,我们已经学会了使用 BaseModel
来构建结构化的数据模型,并通过类型注解与自动校验让模型“活”了起来。
但在实际开发中,仅仅定义字段类型还远远不够,我们通常还需要:
- 给字段添加默认值与描述信息;
- 对字段值设置约束(如最小长度、数值范围等);
- 指定别名(如 API 接口字段和内部字段名不一致);
- 配置模型行为(是否允许额外字段?是否忽略大小写?是否严格类型?)
本章,我们就来详细介绍如何使用 Field
和 model_config
(Pydantic v2 中的新写法)来丰富和定制你的数据模型。
3.1 使用 Field
添加元信息
Pydantic 提供了一个强大的辅助函数 Field()
,它可以用于:
- 设置默认值;
- 附加描述信息(doc);
- 定义约束(如最小值、最大值、正则等);
- 添加示例值、标记为必填字段等。
基本语法:
from pydantic import BaseModel, Field
class User(BaseModel):
id: int = Field(..., description="用户的唯一ID", gt=0)
name: str = Field(..., min_length=2, max_length=50)
age: int = Field(default=18, ge=0, le=150)
参数详解:
参数 | 说明 |
---|---|
default | 默认值(也可使用 ... 表示必填) |
description | 字段的描述信息 |
gt , ge | 大于/大于等于 |
lt , le | 小于/小于等于 |
min_length , max_length | 用于字符串或列表长度限制 |
pattern | 用于正则表达式匹配 |
examples | 示例值,用于自动文档工具(如 FastAPI) |
示例:
class Product(BaseModel):
name: str = Field(..., description="商品名称", min_length=2)
price: float = Field(..., ge=0, description="商品价格,必须为非负数")
tags: list[str] = Field(default_factory=list, description="标签列表")
注意 default_factory
用于生成默认的可变对象(如列表、字典),避免所有实例共享同一个对象。
3.2 字段别名与类型提示
在某些场景中,外部数据的字段名可能与我们内部模型字段名不同。这时候我们可以使用 alias
参数来设置字段别名。
示例:
class Item(BaseModel):
item_id: int = Field(..., alias="id")
item_name: str = Field(..., alias="name")
data = {"id": 1, "name": "Apple"}
item = Item.model_validate(data)
print(item.item_id) # 1
这对于处理 JSON API 特别有用,比如前端传的是 userName
,后端希望统一为 username
:
class User(BaseModel):
username: str = Field(..., alias="userName")
⚠️ 默认情况:只接受别名字段,不能用内部字段名反序列化。但可以通过配置修改,见下节。
3.3 使用 Config
或 model_config
自定义模型行为
在 Pydantic v1 中,我们使用 class Config
来配置模型行为;而在 Pydantic v2 中,这个方式被替换为 model_config
类属性,语义更清晰。
示例一:允许额外字段
class User(BaseModel):
name: str
model_config = {
"extra": "allow"
}
user = User.model_validate({"name": "Alice", "age": 25})
print(user) # age 会被接受但不作为字段暴露
extra
参数可选值:
"ignore"
(默认): 忽略额外字段;"allow"
: 接受并保留额外字段;"forbid"
: 禁止额外字段,超出即报错。
示例二:允许字段别名参与初始化
class User(BaseModel):
username: str = Field(..., alias="userName")
model_config = {
"populate_by_name": True
}
# 可以使用字段名或别名初始化
User.model_validate({"userName": "alice"})
User.model_validate({"username": "alice"})
示例三:启用严格类型检查
默认 Pydantic 会自动进行类型转换,如果你想强制要求类型匹配,可以这样设置:
class StrictModel(BaseModel):
model_config = {
"strict": True
}
class Score(StrictModel):
value: int
Score.model_validate({"value": 100}) # ✅
Score.model_validate({"value": "100"}) # ❌ 报错
🧪 示例练习:定义注册用户模型
我们定义一个注册用户模型,要求如下:
- 用户名必须为 3~20 字母或数字组成;
- 密码长度为 8~32;
- 邮箱为合法格式;
- 接受外部字段名
userName
、userEmail
,但内部统一为username
和email
; - 禁止额外字段;
- 严格类型校验。
import re
from pydantic import BaseModel, Field, EmailStr
class RegisterUser(BaseModel):
username: str = Field(..., min_length=3, max_length=20, pattern=r"^[a-zA-Z0-9]+$", alias="userName")
password: str = Field(..., min_length=8, max_length=32)
email: EmailStr = Field(..., alias="userEmail")
model_config = {
"extra": "forbid",
"populate_by_name": True,
"strict": True
}
使用:
data = {
"userName": "abc123",
"password": "strongP@ss",
"userEmail": "abc@example.com"
}
user = RegisterUser.model_validate(data)
print(user)
🧠 小贴士
- 在 FastAPI 中,
Field(..., description="...")
会自动生成 OpenAPI 文档。 - 使用
default_factory
生成默认值可以避免可变对象共享引用的问题。 model_config
替代了 v1 中的class Config
,但语义一致。
✅ 本章小结
-
使用
Field()
可以设置字段默认值、描述、验证规则和别名。 -
alias
允许你对接不同命名规范的数据(如 JSON 接口)。 -
model_config
提供强大的模型级行为控制能力,如:- 是否允许额外字段;
- 是否启用别名初始化;
- 是否严格类型校验;
-
熟练掌握
Field
与model_config
能大大提升模型的表达力与健壮性。