为何Pydantic使用.dict()时关联模型字段会转为字典?如何修改?
Pydantic .dict()方法将嵌套模型转为字典的原因及修改方案
原因
Pydantic的dict()方法(v1版本)核心设计目标是把模型序列化为原生Python数据结构,方便后续的JSON序列化、数据存储或传输。默认情况下,它会递归处理所有嵌套的Pydantic模型实例,将其转换为字典结构——这是因为原生Python类型(如字典、字符串、数字)是通用的可序列化格式,而自定义模型实例并非所有系统都能直接识别。
而直接遍历模型实例时,迭代器返回的是字段的原始值,也就是未经过序列化处理的模型对象,所以不会被转换为字典。
修改方案
针对Pydantic v1
方法1:直接访问模型的__dict__属性
模型内部通过__dict__存储所有字段的原始值,直接遍历它就能保留嵌套模型实例:
for key, val in model.__dict__.items(): print((key, val))
如果只需要遍历用户显式设置的字段(排除默认值),可以结合__fields_set__筛选:
for key in model.__fields_set__: val = getattr(model, key) print((key, val))
方法2:自定义序列化逻辑(按需使用)
如果需要在dict()方法中保留特定嵌套模型,可以通过重写模型的dict()方法实现,但这种方式会影响整体序列化行为,需谨慎使用:
from pydantic import BaseModel class Model(BaseModel): attr: str class AnotherModel(BaseModel): attr: str model_attr: Model def dict(self, **kwargs): # 先获取基础字典,再替换指定字段为原始实例 result = super().dict(**kwargs) result['model_attr'] = self.model_attr return result model = AnotherModel(attr="test", model_attr=Model(attr="something")) for key, val in model.dict().items(): print((key, val))
针对Pydantic v2
v2版本的model_dump()方法新增了mode参数,设置为'python'即可保留嵌套模型实例,无需额外处理:
from pydantic import BaseModel class Model(BaseModel): attr: str class AnotherModel(BaseModel): attr: str model_attr: Model model = AnotherModel(attr="test", model_attr=Model(attr="something")) for key, val in model.model_dump(mode='python').items(): print((key, val))
内容的提问来源于stack exchange,提问作者lupl
相关产品推荐
相关产品推荐

