如何让Pydantic生成的JSON Schema保留指定字段默认值忽略其他?
问题
使用Pydantic 2.11.7时,定义了如下模型代码:
import json import time from pydantic import BaseModel, Field class SeededModel(BaseModel): seed: int = Field(default_factory=lambda _: int(time.time() * 1000)) sensible_default: bool = False class Base(BaseModel): settings: SeededModel = SeededModel()
运行后生成的JSON Schema如下:
{ "$defs": { "SeededModel": { "properties": { "seed": { "title": "Seed", "type": "integer" }, "sensible_default": { "default": false, "title": "Sensible Default", "type": "boolean" } }, "title": "SeededModel", "type": "object" } }, "properties": { "settings": { "$ref": "#/$defs/SeededModel", "default": { "seed": 1752596882987, "sensible_default": false } } }, "title": "Base", "type": "object" }
需要实现的效果是:为Base#settings设置默认值时,保留SeededModel#sensible_default的默认值,但不保留SeededModel#seed的默认值(即Schema中settings的default字段里不包含seed)。
解决方案
方法一:用default_factory精准控制默认实例
修改Base类中settings字段的定义,通过default_factory创建仅包含sensible_default的SeededModel实例,这样生成的JSON Schema里settings的default就不会包含seed:
import json import time from pydantic import BaseModel, Field class SeededModel(BaseModel): seed: int = Field(default_factory=lambda _: int(time.time() * 1000)) sensible_default: bool = False class Base(BaseModel): # 用default_factory生成只带sensible_default的实例 settings: SeededModel = Field(default_factory=lambda: SeededModel(sensible_default=False)) config_schema = Base.model_json_schema() print(json.dumps(config_schema, indent=2))
生成的Schema中settings部分会变成:
"settings": { "$ref": "#/$defs/SeededModel", "default": { "sensible_default": false } }
实际实例化Base时,seed依然会通过自身的default_factory自动生成,完全不影响功能。
方法二:后处理Schema移除不需要的默认字段
如果不想修改模型定义,可以在生成Schema后手动移除seed字段:
config_schema = Base.model_json_schema() # 移除settings默认值里的seed字段 config_schema["properties"]["settings"]["default"].pop("seed", None) print(json.dumps(config_schema, indent=2))
这种方式简单直接,但属于生成Schema后的修改操作,适合不需要频繁调整的场景。
内容的提问来源于stack exchange,提问作者Tristan F.-R.
相关产品推荐
相关产品推荐

