
本文详解如何使用 skipjsonschema 精准排除 pydantic 模型字段在 model_json_schema() 中的输出,避免 field(exclude=true) 等误用方式导致 schema 仍残留字段的问题。
本文详解如何使用 skipjsonschema 精准排除 pydantic 模型字段在 model_json_schema() 中的输出,避免 field(exclude=true) 等误用方式导致 schema 仍残留字段的问题。
在 Pydantic(尤其是 v2.x)中,开发者常混淆「序列化排除」与「Schema 排除」两个概念:
- Field(exclude=True) 或 model_dump(exclude=…) 仅影响运行时数据序列化(如 model_dump() / model_json()),不影响 JSON Schema 生成;
- Field(exclude_schema=True) 是无效参数——Pydantic v2 并未实现该参数,它会被静默忽略,因此字段仍会出现在 model_json_schema() 输出中(正如问题示例所示)。
✅ 正确方案:使用 pydantic.json_schema.SkipJsonSchema 类型包装器。
SkipJsonSchema[T] 是 Pydantic 官方提供的类型注解工具,用于声明性地告知 JSON Schema 生成器:此字段不应出现在任何 Schema 定义中,包括属性定义、required 列表及 $defs 引用。
✅ 正确用法示例
from pydantic.json_schema import SkipJsonSchema from pydantic import BaseModel import json class MyItem(BaseModel): name: str data: str class MyObject(BaseModel): # ✅ 此字段将完全从 JSON Schema 中消失 items_dict: dict[str, MyItem] = SkipJsonSchema[dict[str, MyItem]] # 其他正常字段照常参与 schema 生成 title: str version: int = 1 # 验证效果 schema = MyObject.model_json_schema() print(json.dumps(schema, indent=2))
输出 Schema 将不包含 items_dict 字段:
{ "properties": { "title": { "title": "Title", "type": "string" }, "version": { "default": 1, "title": "Version", "type": "integer" } }, "required": ["title"], "title": "MyObject", "type": "object" }
⚠️ 注意事项与最佳实践
-
仅作用于 Schema,不影响模型行为:SkipJsonSchema 不改变字段的验证、默认值、赋值逻辑或序列化行为。若还需运行时排除该字段,请额外配合 exclude 参数:
# 同时排除 schema 和序列化结果 internal_cache: SkipJsonSchema[dict] = Field(default_factory=dict, exclude=True) -
不可与 Field(…) 混合用于同一字段:SkipJsonSchema 是类型注解层级的声明,应直接用于字段类型,而非 Field() 的参数。以下写法错误:
# ❌ 错误:SkipJsonSchema 是类型,不是 Field 参数 bad_field: str = Field(..., default=SkipJsonSchema[str]) -
支持嵌套与泛型:可安全用于复杂类型,如 SkipJsonSchema[List[MyModel]]、SkipJsonSchema[Optional[Dict[str, Any]]] 等。
-
文档兼容性:生成的 OpenAPI/Swagger 文档(如 fastapi)会自动尊重 SkipJsonSchema,确保 API 文档不暴露内部字段。
✅ 总结
| 目标 | 推荐方式 |
|---|---|
| 排除 JSON Schema | field_name: SkipJsonSchema[T] |
| 排除序列化输出 | field_name: T = Field(…, exclude=True) |
| 同时排除两者 | field_name: SkipJsonSchema[T] = Field(…, exclude=True) |
牢记:Schema 排除 ≠ 序列化排除。SkipJsonSchema 是 Pydantic v2 中专为 Schema 场景设计的精准控制机制,是解决“字段仍在 schema 中出现”问题的唯一可靠方案。