fastapi默认用pydantic v2因0.95+版本已完全迁移至pydantic>=2.0,依赖其新行为如字段默认值处理和model_validate替代parse_obj。

FastAPI 为什么默认用 Pydantic v2 而不是 v1
因为 FastAPI 0.95+ 已完全迁移到 pydantic>=2.0,底层依赖 BaseModel 的新行为(如字段默认值处理、model_validate 替代 parse_obj)。如果你装了旧版 Pydantic(pydantic),启动时会报错:<code>ImportError: cannot import name 'BaseModel' from 'pydantic' 或更隐蔽的 ValidationError 行为异常。
实操建议:
- 运行
pip install "pydantic>=2.0" "fastapi>=0.104"确保版本兼容 - 检查
pydantic.VERSION是否为"2.x",避免混用from pydantic import BaseModel(v2)和from pydantic_v1 import BaseModel(v1) - v2 中
Field(default=...)和Field(default_factory=...)语义更严格,空字符串或None不再被自动跳过校验
如何用 Pydantic 模型校验 POST 请求体(JSON)
FastAPI 把函数参数标注为 BaseModel 子类时,会自动解析 JSON 并调用 model_validate。这不是“手动调用”,而是框架在后台完成的完整生命周期:反序列化 → 类型转换 → 验证 → 实例化。
常见错误现象:
- 传了字符串
"123"给age: int字段,返回 422 错误,但错误信息里显示Input should be a valid integer—— 这是 Pydantic v2 的默认提示,不是 bug - 漏传必填字段,错误响应中
loc是["body", "field_name"],说明校验发生在请求体层级 - 字段名含下划线(如
user_name),但前端传的是userName(驼峰),默认不自动转换 —— 需显式配置model_config = ConfigDict(alias_generator=lambda s: s.replace('_', ''))或用Field(alias="userName")
示例:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
from pydantic import BaseModel, Field
from fastapi import FastAPI
class UserCreate(BaseModel):
name: str = Field(min_length=2, max_length=50)
age: int = Field(gt=0, le=150)
email: str
app = FastAPI()
@app.post("/users")
def create_user(user: UserCreate):
return {"id": 1, **user.model_dump()}
如何处理查询参数(Query)、路径参数(Path)和表单(Form)的类型校验
Pydantic 模型只用于请求体(Body),其余参数类型需用 FastAPI 自带的 Query、Path、Form 等依赖项。它们内部也复用 Pydantic 校验逻辑,但写法不同。
使用场景与要点:
-
Query参数若带类型注解(如q: str | None = None),FastAPI 会自动加str校验;若需额外约束,必须用Query(min_length=1) -
Path参数不支持None,必须提供默认值或标记为必填,否则报TypeError: Path parameter ... is required -
Form不支持嵌套模型,只能平铺字段;若要接收文件 + 其他字段,得用UploadFile和Form混合,且所有非文件字段必须显式声明= Form(...) - 所有这些参数最终都走同一套校验引擎,错误响应结构一致,只是
loc变成["query", "q"]或["path", "item_id"]
为什么 model_dump() 比 dict() 更安全
dict() 是 Pydantic v1 的方法,在 v2 中已被弃用,直接调用会触发 DeprecationWarning;而 model_dump() 是 v2 官方推荐方式,支持更多选项(如 exclude_unset=True 排除未设置字段、by_alias=True 使用别名键名)。
容易踩的坑:
- 在路由函数里返回
user.dict(),本地跑得通但 CI 报 warning,上线后某天升级 Pydantic 就崩 - 用
model_dump(mode="json")时,datetime字段自动转成 ISO 字符串,但若字段是Optional[datetime]且为None,结果是null—— 这是预期行为,不是 bug - 如果模型里有自定义
@computed_field,它不会出现在model_dump(exclude_unset=True)结果里,除非显式加include={"my_field"}
复杂点在于:校验和序列化看似一体,实则分属两个阶段。你改了 model_config 的 json_encoders,只影响输出,不影响入参校验逻辑。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










