Skip to content

数据校验与 Pydantic ​

校验分三层理解 ​

层次例子常见处理位置
结构与类型年龄应是整数Pydantic、参数声明
字段与字段关系结束时间晚于开始时间模型校验器
业务与外部状态用户名未被占用、库存充足业务函数、数据库约束

“价格是正数”可以在字段规则里检查;“商品当前还有多少库存”往往要查询数据库。不要把所有业务判断都放进模型校验器。

常见约束 ​

约束含义示例
gt大于gt=0
ge大于等于ge=0
lt小于lt=100
le小于等于le=100
min_length字符串或容器最短长度min_length=1
max_length字符串或容器最长长度max_length=100
pattern字符串正则规则pattern=r"^[A-Za-z0-9_]+$"

在请求体字段中使用 Field();在查询参数中使用 Query();在路径参数中使用 Path()。规则相似,但参数所在的位置不同。官方字段校验说明、官方路径数值校验说明

完整示例:清理标题并拒绝空白 ​

python
from fastapi import FastAPI
from pydantic import BaseModel, ConfigDict, Field, field_validator

app = FastAPI()


class ArticleCreate(BaseModel):
    model_config = ConfigDict(extra="forbid")

    title: str = Field(min_length=1, max_length=100)
    content: str = Field(min_length=1)

    @field_validator("title")
    @classmethod
    def validate_title(cls, value: str) -> str:
        cleaned = value.strip()
        if not cleaned:
            raise ValueError("标题不能只有空格")
        return cleaned


@app.post("/articles", status_code=201)
def create_article(article: ArticleCreate):
    return article

这里的 field_validator 默认在字段基础解析之后执行。value 是待检查的标题,返回值会成为模型中最终保存的标题。

extra="forbid" 表示客户端不能偷偷多传未定义的字段。Pydantic 模型默认通常会忽略多余字段;选择忽略还是拒绝,应按接口约定决定。Pydantic 模型说明、Pydantic 校验器说明

必填、默认值、空值 ​

定义能省略吗能传 null 吗
name: str不能不能
name: str = "未命名"能不能
name: str | None不能能
name: str | None = None能能

这个表对 Pydantic 2 模型字段尤其重要。允许 None 只说明取值范围,不自动表示字段可省略。 Pydantic 必填与可空字段迁移说明

类型转换与严格模式 ​

常见情况下,Pydantic 会尝试将合法的数字文本转换为数字,例如模型中的 count: int 可能接受 "3"。但它不会把任意不合法内容变成你想要的数据。

如果业务要求 JSON 中必须真的提供整数,可为对应字段使用严格类型,例如:

python
from pydantic import BaseModel, StrictInt


class CountInput(BaseModel):
    count: StrictInt

这个字段会拒绝字符串 "3"。查询参数天然来自文本,不宜不加判断地照搬 JSON 字段的严格策略。Pydantic 严格模式说明

Pydantic 2 常用方法 ​

以下是独立语法示例:

python
from pydantic import BaseModel


class Note(BaseModel):
    title: str
    description: str | None = None


note = Note(title="学习计划")
print(note.model_dump())
print(note.model_dump_json())
print(note.model_dump(exclude_unset=True))
parsed = Note.model_validate({"title": "第二份计划"})
方法用途
model_dump()转为 Python 字典
model_dump(mode="json")输出适合 JSON 的数据类型
model_dump_json()转为 JSON 字符串
model_validate(data)解析并校验输入数据
model_dump(exclude_unset=True)仅保留客户端显式提供过的字段

exclude_unset=True 在 PATCH 中非常重要。它依据“有没有传过字段”,不是依据值是否为 None。

识别旧教程写法 ​

常见旧写法本手册采用的 Pydantic 2 写法
.dict().model_dump()
.json().model_dump_json()
.parse_obj().model_validate()
orm_mode = TrueConfigDict(from_attributes=True)
@validator@field_validator
从 pydantic 导入 BaseSettings从 pydantic_settings 导入

这张表是识别方向,不是完整的自动替换规则。校验器行为、配置方式等还有变化,迁移真实项目时应检查官方迁移说明。Pydantic 2 迁移指南

本章练习 ​

定义注册模型:用户名 3~20 个字符,年龄 18~120,用户名只能使用字母、数字和下划线,拒绝额外字段。

过关标准:能区分类型错误、字段错误与业务错误,并解释省略字段和显式空值的区别。