第四章:Field():给字段加上约束
类型注解只能约束"是什么类型",但真实需求往往是:"长度 3~20"、"必须大于 0"、"要符合某个正则"。这就是 Field() 的用武之地。
4.1 基本用法
python
from pydantic import BaseModel, Field
class Product(BaseModel):
name: str = Field(min_length=1, max_length=50)
price: float = Field(gt=0) # 必须大于 0
stock: int = Field(ge=0, le=9999) # 0 ~ 9999
sku: str = Field(pattern=r"^[A-Z]{3}-\d{4}$") # 正则:如 ABC-1234
discount: float = Field(default=0, ge=0, lt=1)常用约束速查:
| 约束 | 含义 | 适用类型 |
|---|---|---|
gt / ge | 大于 / 大于等于 | 数字 |
lt / le | 小于 / 小于等于 | 数字 |
min_length / max_length | 长度范围 | str、list 等 |
pattern | 正则匹配 | str |
default | 默认值 | 所有 |
default_factory | 默认值工厂函数 | 所有 |
4.2 default vs default_factory(重要!)
python
from datetime import datetime
class Log(BaseModel):
tags: list[str] = Field(default_factory=list) # ✅ 每次新建一个空列表
created_at: datetime = Field(default_factory=datetime.now) # ✅ 每次取当前时间规则:默认值是"会变的东西"(列表、字典、当前时间等),必须用 default_factory;不可变的常量(数字、字符串、None)才用 default。这和 dataclass 的坑一模一样。
4.3 别名:应对奇怪的字段名
接口返回的 JSON 字段名有时不符合 Python 命名习惯,别名(alias)来救场:
python
class User(BaseModel):
user_id: int = Field(alias="userId") # JSON 里是 userId,代码里用 user_id
user_name: str = Field(alias="userName")
data = {"userId": 1, "userName": "小明"}
user = User.model_validate(data)
print(user.user_id) # 14.4 描述信息:为文档服务
python
class User(BaseModel):
name: str = Field(description="用户真实姓名", examples=["张三", "李四"])这些信息会进入生成的 JSON Schema(第十一章),FastAPI 的自动文档全靠它们。