Skip to content

第四章: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)   # 1

4.4 描述信息:为文档服务 ​

python
class User(BaseModel):
    name: str = Field(description="用户真实姓名", examples=["张三", "李四"])

这些信息会进入生成的 JSON Schema(第十一章),FastAPI 的自动文档全靠它们。