You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Pydantic Schema中排除内部字段?

Pydantic内部字段无法排除序列化及Schema的解决方法

我在Pydantic类中定义了一个内部字段items_dict,仅用于内部逻辑处理,不需要被序列化,也不想让它出现在生成的Schema里。尝试使用Field的exclude=True和exclude_schema=True参数后,问题依然存在,生成的Schema中该字段仍会显示。

我的代码实现

from pydantic import BaseModel, Field, root_validator
import json

class MyItem(BaseModel):
    name: str = Field(...)
    data: str = Field(...)

def validate_items(items):
    # 自定义验证逻辑,将列表转为字典
    return {item.name: item for item in items}

class MyObject(BaseModel):
    items_dict: dict[str, MyItem] = Field(..., exclude=True, exclude_schema=True)
    
    @property
    def items_list(self):
      return list(self.items_dict.values())

    @root_validator(pre=True)
    @classmethod
    def encode_decode_items(cls, values):
        items = values.get('items_dict')
        if isinstance(items, dict):
            values['items_dict'] = list(items.values())
        elif isinstance(items, list):
            values['items_dict'] = validate_items(items)
        return values

obj = MyObject(items_dict=[MyItem(name='item1', data='data1'), MyItem(name='item2', data='data2')])

print(json.dumps(obj.model_json_schema(), indent=2))

问题现象

运行代码后,生成的Schema依然包含items_dict字段:

{
  "$defs": {
    "MyItem": {
      "properties": {
        "name": {
          "title": "Name",
          "type": "string"
        },
        "data": {
          "title": "Data",
          "type": "string"
        }
      },
      "required": [
        "name",
        "data"
      ],
      "title": "MyItem",
      "type": "object"
    }
  },
  "properties": {
    "items_dict": {
      "additionalProperties": {
        "$ref": "#/$defs/MyItem"
      },
      "exclude_schema": true,
      "title": "Items Dict",
      "type": "object"
    }
  },
  "required": [
    "items_dict"
  ],
  "title": "MyObject",
  "type": "object"
}

可行的解决办法

方法1:通过model_config配置全局排除

在MyObject类中添加model_config,同时指定exclude和private_attributes,从根源上排除该字段的序列化和Schema生成:

class MyObject(BaseModel):
    items_dict: dict[str, MyItem] = Field(...)
    
    @property
    def items_list(self):
      return list(self.items_dict.values())

    @root_validator(pre=True)
    @classmethod
    def encode_decode_items(cls, values):
        items = values.get('items_dict')
        if isinstance(items, dict):
            values['items_dict'] = list(items.values())
        elif isinstance(items, list):
            values['items_dict'] = validate_items(items)
        return values

    model_config = {
        "exclude": {"items_dict"},
        "private_attributes": {"items_dict"}
    }

方法2:改用PrivateAttr定义纯内部字段

如果字段仅用于内部逻辑,不需要对外暴露,可以使用PrivateAttr定义(注意字段名需加下划线前缀),这样字段不会被纳入Schema和序列化流程:

from pydantic import PrivateAttr

class MyObject(BaseModel):
    _items_dict: dict[str, MyItem] = PrivateAttr(default_factory=dict)
    
    @property
    def items_list(self):
      return list(self._items_dict.values())

    @root_validator(pre=True)
    @classmethod
    def encode_decode_items(cls, values):
        items = values.pop('items_dict')
        if isinstance(items, dict):
            items = list(items.values())
        values['_items_dict'] = validate_items(items)
        return values

这种方式需要调整root_validator的逻辑,将输入的items_dict转为内部的_items_dict。

方法3:序列化时手动排除(仅解决序列化问题)

如果只是不想序列化该字段,但可以接受它出现在Schema中,可在序列化时指定exclude参数:

# 序列化时排除items_dict
print(obj.model_dump(exclude={"items_dict"}))

但此方法不会影响Schema生成,仅适用于序列化场景。

内容的提问来源于stack exchange,提问作者Aviad Rozenhek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:32:47