pydantic v2 中需调用 exc.errors() 才能批量获取所有 validationerror;返回扁平 list,每项含 loc(tuple 路径)、msg、type 等字段,loc[0] 可结合 model.model_fields[loc[0]].alias 映射前端字段名。

Pydantic v2 的 ValidationError 怎么批量提取所有错误?
默认只报第一个错误,不是 bug,是设计如此——为了快。想收全,得主动调用 errors() 方法。
-
errors()返回的是 list,每个元素是 dict,含loc、msg、type等字段,loc是 tuple,比如('age',)或('items', 0, 'name') - 别直接 print
exc对象,那只会显示第一条;要显式捕获后调exc.errors() - v1 用
exc.errors(),v2 同名但返回结构更扁平,不嵌套ctx字段了,升级时注意字段访问方式
用 validate_python() 还是 model_validate()?
二者都走校验逻辑,但入口不同:前者是底层 API,后者是模型方法。日常用 model_validate() 更稳。
-
model_validate()自动处理from_attributes=True场景(比如 ORM 实例转模型),validate_python()不管这个 -
validate_python()允许传context和strict,适合测试或特殊解析流程;普通业务校验没必要绕路 - 如果用了
@field_validator,两种方式都触发;但若字段有default_factory,model_validate()会按需构造,默认值逻辑更完整
自定义错误收集:怎么让 ValidationError 带上原始输入字段名?
默认 loc 是路径式元组,前端难映射。得靠 title + 自定义 json_schema_extra 配合后处理。
- 在字段定义里加
alias,比如user_name: str = Field(..., alias='userName'),loc仍为('user_name',),但可用model.model_json_schema()['properties']反查别名 - 更直接的做法:捕获异常后遍历
exc.errors(),对每个loc[0]查模型字段的alias属性(通过model.model_fields[loc[0]].alias) - 别改
loc本身——那是内部定位路径,强行替换会导致model_dump(exclude_unset=True)等行为异常
FastAPI 里怎么把校验错误转成统一 JSON 格式?
FastAPI 默认返回的 error structure 嵌套深、字段名不一致(比如 detail vs errors),需要中间层拦截。
立即学习“Python免费学习笔记(深入)”;
- 写个异常处理器,匹配
RequestValidationError,再从exc.body和exc.errors()拼出扁平字段级错误列表 - 注意:FastAPI 的
RequestValidationError和 Pydantic 的ValidationError不是同一个类,前者包装后者,得取exc.errors()而非exc.exc.errors() - 如果用了依赖注入(Depends),校验失败发生在依赖解析阶段,错误类型仍是
RequestValidationError,处理逻辑不变
exc 结构,很容易按文档字面理解错。










