Pydantic如何存储模型未定义属性?(类C# JsonExtensionData)
Pydantic处理JSON额外字段的实现(对应C# JsonExtensionData)
Pydantic提供了专门的机制来处理JSON中超出模型定义的额外字段,功能和C#的JsonExtensionData特性一致,分两个主流版本说明具体实现:
Pydantic v2
1. 允许额外字段并直接访问
通过在模型的model_config中设置extra='allow',JSON中的额外字段会被自动添加到模型实例中,既可以直接作为属性访问,也能通过model_extra字典统一获取:
from pydantic import BaseModel, ConfigDict class MyModel(BaseModel): model_config = ConfigDict(extra='allow') foo: str bar: int # 测试包含额外字段的JSON数据 json_data = {"foo": "hello", "bar": 42, "baz": "extra value"} my_model = MyModel(**json_data) # 获取额外字段'baz'的两种方式 print(my_model.baz) # 直接访问属性,输出: extra value print(my_model.model_extra.get('baz')) # 从model_extra字典获取,输出: extra value
2. 将额外字段统一存入指定模型字段
如果你希望把所有额外字段集中存储到模型的某个特定字段中,可以结合model_validator实现:
from pydantic import BaseModel, ConfigDict, model_validator class MyModel(BaseModel): model_config = ConfigDict(extra='forbid') # 禁止直接添加额外字段到实例 foo: str bar: int extra_data: dict = {} @model_validator(mode='before') def collect_extra_fields(cls, values): # 分离已知字段和额外字段 known_fields = cls.model_fields.keys() extra = {k: v for k, v in values.items() if k not in known_fields} values['extra_data'] = extra # 返回仅包含已知字段的字典 return {k: v for k, v in values.items() if k in known_fields} json_data = {"foo": "hello", "bar": 42, "baz": "extra value", "qux": 123} my_model = MyModel(**json_data) print(my_model.extra_data) # 输出: {'baz': 'extra value', 'qux': 123}
Pydantic v1
v1版本通过Config类的extra属性控制额外字段的处理逻辑,使用Extra.allow允许额外字段:
from pydantic import BaseModel, Extra class MyModel(BaseModel): class Config: extra = Extra.allow foo: str bar: int json_data = {"foo": "hello", "bar": 42, "baz": "extra value"} my_model = MyModel(**json_data) # 获取额外字段'baz' print(my_model.baz) # 直接访问属性,输出: extra value print(my_model.__dict__.get('baz')) # 从实例字典获取,输出: extra value
如果需要将额外字段存入指定字段,可使用root_validator:
from pydantic import BaseModel, Extra, root_validator class MyModel(BaseModel): class Config: extra = Extra.forbid foo: str bar: int extra_data: dict = {} @root_validator(pre=True) def collect_extra_fields(cls, values): known_fields = cls.__fields__.keys() extra = {k: v for k, v in values.items() if k not in known_fields} values['extra_data'] = extra return {k: v for k, v in values.items() if k in known_fields} json_data = {"foo": "hello", "bar": 42, "baz": "extra value"} my_model = MyModel(**json_data) print(my_model.extra_data) # 输出: {'baz': 'extra value'}
内容的提问来源于stack exchange,提问作者koks der drache
相关产品推荐
相关产品推荐

