pydantic 之 Field 使用教程

3239 字
16 分钟
pydantic 之 Field 使用教程

下面提供一个针对 Pydantic 中 Field 的通俗易懂、又较为全面的中文教程,适合初学者(“小白”)理解和上手。内容包括 Field 的作用、常用参数、在模型验证和文档生成中的意义,以及丰富的示例与注意事项。


一、什么是 Pydantic 和 Field#

  • Pydantic 是一个用于数据校验和设置的 Python 库,常用于 FastAPI、数据处理脚本等场景。它通过 Python 类型注解(type hints)来定义数据模型,并在实例化时自动校验和转换输入数据。
  • Field 是 Pydantic 提供的一个函数/标记,用于在模型属性(字段)上指定更丰富的元信息和校验约束。例如:默认值、校验范围、描述文档、示例、别名等。

简单来说,Field 就像给模型字段“贴标签”,告诉 Pydantic 该字段应如何校验、如何在 OpenAPI 文档中展示、默认值是多少等。


二、Field 的基本用法#

2.1 导入与基本语法#

from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(...) # “...” 表示必须提供该字段
age: int = Field(default=0) # 如果不提供,默认为 0
  • Field(...) 中通常第一个参数是 default 或 default_factory:
    • Field(default_value):若用户未提供该字段,则使用 default_value
    • Field(...)... 表示“这个字段必填”(no default),如果创建模型时未提供会报错。
    • Field(default_factory=callable):通过可调用对象生成默认值,如 Field(default_factory=list) 表示默认 [],每次新实例化时调用一次函数以免所有实例共用同一个可变默认。

2.2 最简单示例#

class Item(BaseModel):
name: str = Field(..., title="名称", description="项目名称,必填")
price: float = Field(0.0, gt=0, description="价格,必须大于0")
  • name:使用 Field(..., title="名称", description="项目名称,必填") 强调必填,并添加标题和描述,方便自动生成文档。
  • price:默认值为 0.0,同时用 gt=0 约束大于 0;若输入为负数或 0,会报校验错误。

三、Field 常用参数详解#

以下列出 Field(...) 中常见的参数及其作用,便于理解和记忆。格式:Field(default, 参数名=值, ...)

  1. default / default_factory
    • default:字段默认值,如 Field(5)Field("abc")Field(None)
    • default_factory:可调用,用于生成默认值,如 Field(default_factory=list)Field(default_factory=lambda: datetime.utcnow())
    • 注意:default 和 default_factory 不能同时使用。
  2. 校验约束(numeric、string、序列等)
    • 数值类型:gtgeltle
      • gt: “greater than”,严格大于;ge: “greater or equal”,大于等于;同理 ltle
      • 示例:age: int = Field(..., ge=0, lt=150) 表示年龄在 [0,150) 之间。
    • 字符串长度:min_lengthmax_length
      • 仅对字符串类型有效:name: str = Field(..., min_length=1, max_length=50)
    • 正则表达式:regex
      • phone: str = Field(..., regex=r"^\d{10,11}$"),确保字符串满足正则。
    • 列表/集合类型长度:min_itemsmax_items
      • 对序列类型生效:tags: List[str] = Field(default_factory=list, min_items=1, max_items=5)
    • 数组元素校验:可配合 Pydantic 泛型和子模型使用,Field 本身不对元素类型做深度校验,但 Pydantic 会结合类型注解校验每个元素类型。
  3. 文档和元信息
    • title:字段标题,在自动生成文档(如 OpenAPI/Swagger)中显示为该字段的标题。
    • description:字段描述,自动文档中显示详细说明。
    • example 或 examples:在 Pydantic V1 中,schema_extra 用于示例;在 FastAPI 自动文档中,可在路由中定义 example。Field 也支持 example(Pydantic V2 支持),或通过 schema_extra 全局添加。
    • alias:字段别名,表示 JSON 输入/输出时使用的键名。例如:
class User(BaseModel):
full_name: str = Field(..., alias="fullName")
- 创建时可用 `{ "fullName": "张三" }`,但访问属性时为 `user.full_name`。
- 设置 `Config` 中 `allow_population_by_field_name = True` 可以同时支持通过属性名赋值。
- `const`(仅 Pydantic V2):表示字段值必须恒定(与 default 一致),类似常量。
- `deprecated`: 标记字段已过时(在自动文档里提示废弃)。
- `multiple_of`: 对数值类型,要求可被某个数整除。
- `strict`: 是否开启严格模式(例如类型强转限制更严),Pydantic V1 / V2 具体差异需参考对应版本文档。

4. 校验顺序细节 - Pydantic 会先按照类型注解对传入值做类型转换(如 "123" 转为 int 123),然后再检查 Field 中的约束(如 geregex 等)。如果类型转换失败或约束检查失败,就抛出 ValidationError。 - 对可选类型(Optional[...] 或 Union[..., None])允许 None,但若 Field 加了 min_length 等检查,在值为 None 时会跳过对应检查或报错,视具体情况而定。建议 Optional 字段不要加不适用的约束。 5. 示例:多个约束组合

from typing import List, Optional
from pydantic import BaseModel, Field
class Product(BaseModel):
id: int = Field(..., gt=0, description="商品 ID,必须正整数")
name: str = Field(..., min_length=1, max_length=100, description="商品名称,1-100 字符")
price: float = Field(..., ge=0.0, description="价格,不可为负")
tags: List[str] = Field(default_factory=list, min_items=0, max_items=10, description="标签列表,最多 10 项")
description: Optional[str] = Field(None, max_length=500, description="商品描述,最多 500 字")

四、用于 FastAPI 自动文档#

  在 FastAPI 中使用 Pydantic 模型作为请求体或响应模型时,Field 提供的 titledescriptionexamplealias 等元信息会自动体现在 Swagger UI 或 Redoc 中,让前后端协作更流畅。 示例:

from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(..., title="名称", description="商品名称", example="苹果")
price: float = Field(..., gt=0, description="价格,必须大于 0", example=9.9)
@app.post("/items", response_model=Item)
def create_item(item: Item):
# item.name, item.price 都已校验通过
return item
  • 在 Swagger UI 的请求体示例中,会显示字段名称、示例值、描述等,帮助前端理解如何调用接口。
  • 如果使用 alias,在文档中也会展示别名,注意需在模型 Config 中设置 allow_population_by_field_name 以兼容。

五、Field 与 Config 结合使用#

Pydantic 模型还支持 Config 内部类来配置更多全局行为。常见与 Field 结合的配置:

  1. orm_mode = True
    • 当返回数据库 ORM 对象(如 SQLAlchemy model)时,可直接通过 Pydantic 模型序列化。Field 中的约束仍生效。
    • 示例:
class UserOut(BaseModel):
id: int
username: str
class Config:
orm_mode = True
- FastAPI 会自动用 Pydantic 将 ORM 返回的对象转换为 dict,再由 ORJSONResponse 等序列化发送。

2. allow_population_by_field_name = True - 如果你在 Field 中使用 alias,此配置允许在初始化模型时使用字段名赋值。

class User(BaseModel):
full_name: str = Field(..., alias="fullName")
class Config:
allow_population_by_field_name = True
user = User(fullName="张三")
user2 = User(full_name="李四") # 也可这样
- 在 FastAPI 请求场景中,一般前端传递 JSON 用 alias 即可;若需要在 Python 代码中以属性名创建实例,可启用此选项。

3. use_enum_values = True - 如果字段是枚举类型(Enum),可以让 Pydantic 在序列化时使用枚举的值而非名称。常与 Field 一起使用枚举字段。

from enum import Enum
class Role(str, Enum):
admin = "admin"
user = "user"
class User(BaseModel):
username: str
role: Role = Field(default=Role.user, description="角色")
class Config:
use_enum_values = True
  1. validate_assignment = True
    • 允许在模型实例属性赋值时重新校验。若你希望对运行时修改字段做校验,可开启此项。
class Person(BaseModel):
age: int = Field(..., ge=0)
class Config:
validate_assignment = True
p = Person(age=10)
p.age = -5 # 立即抛 ValidationError
  1. Pydantic V2 中的更多配置
    • 如果使用 Pydantic V2,Field 参数与 Config 选项可能有更新,建议查看官方文档。但大多数概念相通:Field 用于字段级别元信息和校验,Config 用于模型级全局行为。

六、默认值与 default_factory 深度说明#

  • default:若字段常量或不依赖运行时数据,用 Field("abc")Field(123)
  • default_factory:当默认值需要在运行时生成、或是可变对象(列表、字典)时,用 default_factory,避免多个实例共用同一可变对象。例如:
class Data(BaseModel):
items: list[int] = Field(default_factory=list)
  • 注意:不要把可变默认写在直接赋值上,如 items: list[int] = [],Pydantic 可能会将同一个列表在多个实例间共享,引发意外。改用 default_factory=list
  • 使用场景:当默认值需根据当前时间动态生成时,可以:
from datetime import datetime
class Event(BaseModel):
created_at: datetime = Field(default_factory=datetime.utcnow)

七、高级示例:嵌套模型与 Field#

当模型中嵌套其他 Pydantic 模型时,Field 也可为嵌套模型字段提供默认值或元信息:

class Address(BaseModel):
city: str = Field(..., description="城市")
zip_code: str = Field(..., regex=r"^\d{5}$", description="邮政编码5位数字")
class User(BaseModel):
username: str = Field(..., min_length=1)
address: Address = Field(..., description="用户地址信息")
  • 如果需要默认嵌套值,可用 default_factory
class User(BaseModel):
username: str = Field(...)
address: Address = Field(default_factory=lambda: Address(city="未知", zip_code="00000"))
  • 嵌套校验:Pydantic 会递归校验嵌套模型,每个字段的 Field 约束都会生效。

八、Field 在 Schema/JSON Schema 生成中的作用#

  • Pydantic 模型可以生成 JSON Schema,用于文档、前端校验等。Field 中的元信息会映射到 JSON Schema:

    • title → "title"
    • description → "description"
    • default → "default"
    • example → "example"
    • gtle 等数值约束 → "minimumExclusive""maximumInclusive" 等(具体名称依据 JSON Schema 版本)
    • regex → "pattern"
  • FastAPI 利用 Pydantic 的 JSON Schema 生成 OpenAPI 文档,Field 中填的描述和示例都会显示在 Swagger UI 中,帮助前端更好理解接口。

可通过以下方式查看生成的 Schema:

from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(..., title="用户名", min_length=1, max_length=32)
age: int = Field(0, ge=0, le=150)
# 查看 JSON Schema
print(User.schema_json(indent=2, ensure_ascii=False))

结果中会看到 "title": "用户名""minLength": 1"maximum": 150 等信息。


九、错误与调试#

  1. ValidationError 信息
    • 当实例化模型时,如果输入不符合 Field 约束,Pydantic 会抛出 ValidationError,并给出详细错误位置和类型。例如:
try:
User(username="", age=-5)
except ValidationError as e:
print(e.json())
- 错误信息会指出哪个字段、哪种校验失败(如 `ensure this value has at least 1 characters`、`value is not greater than 0` 等),帮助快速定位问题。

2. 调试 Field 约束 - 如果某个约束似乎无效,首先确认字段类型注解是否正确,如 age: int 才会应用 gtge;如果是 Optional[int],需要注意 None 行为。 - 确认是否在模型 Config 中有影响验证行为的设置(如 validate_assignmentarbitrary_types_allowed 等)。 - 对于复杂正则,请在单独环境测试正则再放到 Field 中。 3. 兼容 Pydantic V1 vs V2 - 不同版本 Field 参数可能略有差异,若项目升级 Pydantic,需参考对应版本文档。大多数常用参数(gt, ge, min_length 等)在两版中类似。


十、实战小结#

  1. 为什么要用 Field
    • 校验约束:通过 Field 指定范围、长度、正则等,自动校验输入数据,保证数据质量。
    • 自动文档:在 FastAPI 等框架中,Field 的 titledescriptionexample 会自动体现在 Swagger UI 上,极大提高前后端沟通效率。
    • 默认值与动态默认:用 default 和 default_factory 管理默认值,避免可变默认陷阱。
    • 别名与序列化定制:通过 alias 控制 JSON 键名,使内部属性和外部接口字段解耦;配合 Config,可双向赋值。
    • Schema 生成:Field 元信息会体现在生成的 JSON Schema 中,可用于前端校验、文档生成、客户端生成代码等。
  2. 如何学习和验证
    • 多写小示例,在 REPL 或脚本中实例化模型,观察校验行为;打印 Model.schema_json() 查看生成 Schema。
    • 在 FastAPI 项目中试用 Field 的各种参数,打开 /docs 看效果;结合 Postman/Swagger 测试边界情况。
    • 阅读官方文档:Pydantic Field 章节(确认 Pydantic 版本),理解 JSON Schema 映射规则。
  3. 常见注意事项
    • 可变默认使用 default_factory;避免把业务逻辑放在 Field,Field 只做数据定义和校验,不适合写额外复杂逻辑。
    • 校验与业务分离:Field 负责基础类型和简单约束(范围、长度、格式);更复杂的业务校验(如唯一性检查、跨字段关联校验)可在代码中或 Pydantic 的 @root_validator/自定义验证函数中实现。
    • 配合 Config 做更高级用法:如 ORM 模式、别名、严格模式、验证赋值等。

附:一个综合示例#

from typing import List, Optional
from datetime import datetime
from enum import Enum
from pydantic import BaseModel, Field, root_validator, ValidationError
class Role(str, Enum):
admin = "admin"
user = "user"
guest = "guest"
class Address(BaseModel):
city: str = Field(..., description="城市名", min_length=1)
zip_code: str = Field(..., regex=r"^\d{5}$", description="5 位邮编")
class UserIn(BaseModel):
username: str = Field(..., min_length=3, max_length=32, description="用户名,3-32 字符")
password: str = Field(..., min_length=6, description="密码,至少6位")
age: Optional[int] = Field(None, ge=0, le=120, description="年龄,可选,0-120")
roles: List[Role] = Field(default_factory=lambda: [Role.user], description="用户角色列表")
address: Optional[Address] = Field(None, description="地址信息")
created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
bio: Optional[str] = Field(None, max_length=200, description="个人简介,不超过200字符")
@root_validator
def check_age_for_role(cls, values):
age = values.get("age")
roles = values.get("roles", [])
# 假设逻辑:如果未满18岁,不允许 admin 角色
if age is not None and age < 18 and Role.admin in roles:
raise ValueError("未满18岁用户不能拥有 admin 角色")
return values
class Config:
orm_mode = True
allow_population_by_field_name = True
# 测试
try:
u = UserIn(
username="张三",
password="secret123",
age=16,
roles=["user", "admin"], # 触发 root_validator 报错
address={"city": "北京", "zip_code": "10001"}
)
except ValidationError as e:
print("校验错误:", e)
# 查看 schema
print(UserIn.schema_json(indent=2, ensure_ascii=False))
  • 通过 Field 指定了多种约束、默认值、描述等;嵌套 Address 模型也带 Field 校验;使用 Enum 角色;root_validator 做跨字段校验;Config 开启 ORM 模式和别名赋值支持;最后生成 JSON Schema 可用于文档或前端校验。

以上即 Pydantic Field 的全面教程,从基本语法到常用参数、FastAPI 文档支持、Config 结合、高级示例、注意事项等,覆盖了初学者需要了解的大部分内容。建议在实际项目中多练习,打开 Swagger 文档观察效果,逐步加深理解。祝你学习顺利!

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
pydantic 之 Field 使用教程
https://kianzhao.site/posts/pydantic-field/
作者
Kian Zhao
发布于
2026-05-07
许可协议
CC BY-NC-SA 4.0
随机文章 随机推荐
Profile Image of the Author
Kian Zhao
Hello, I'm Kian Zhao.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
19
分类
6
标签
22
总字数
23,111
运行时长
0
最后活动
0 天前

目录