如何在Pydantic模型中序列化/反序列化私有字段?
解决Pydantic私有字段序列化/反序列化并持久化到MongoDB的问题
要让Pydantic模型中的私有字段(以下划线开头)参与JSON序列化/反序列化,同时能正常持久化到MongoDB,只需调整Pydantic的模型配置即可,分版本说明如下:
Pydantic v2 解决方案
在模型中添加model_config配置,开启private_attributes选项,让下划线开头的属性被视为模型的一部分,参与序列化和反序列化流程:
from datetime import datetime from pydantic import BaseModel class MyModel(BaseModel): public_field: str _creation_time: str # 关键配置:允许私有属性参与序列化/反序列化 model_config = {"private_attributes": True} def __init__(self, public_field: str): super().__init__(public_field=public_field, _creation_time=str(datetime.now())) # 序列化测试 model = MyModel(public_field='foo') json_str = model.json() print(json_str) # 输出:{"public_field": "foo", "_creation_time": "2023-03-03 09:43:47.796720"} # 反序列化测试 parsed_model = MyModel.model_validate_json(json_str) print(parsed_model._creation_time) # 输出对应的时间字符串
Pydantic v1 解决方案
v1版本通过Config类设置underscore_attrs_are_private=False,取消下划线属性的私有标记:
from datetime import datetime from pydantic import BaseModel class MyModel(BaseModel): public_field: str _creation_time: str class Config: # 让下划线开头的字段不被视为私有,参与序列化/反序列化 underscore_attrs_are_private = False def __init__(self, public_field: str): super().__init__(public_field=public_field, _creation_time=str(datetime.now())) # 序列化测试 model = MyModel(public_field='foo') json_str = model.json() print(json_str) # 输出包含_creation_time的JSON # 反序列化测试 parsed_model = MyModel.parse_raw(json_str) print(parsed_model._creation_time)
持久化到MongoDB的操作
配置完成后,模型序列化后的字典或JSON可以直接存入MongoDB,查询时再反序列化为模型对象:
from pymongo import MongoClient # 连接MongoDB client = MongoClient('mongodb://localhost:27017/') db = client['test_db'] collection = db['test_models'] # 插入数据:用model_dump()(v2)或dict()(v1)转成字典存入 collection.insert_one(model.model_dump()) # 查询并反序列化 doc = collection.find_one({'public_field': 'foo'}) if doc: # 移除MongoDB自动生成的_id字段(如果不需要) doc.pop('_id', None) # v2用model_validate,v1用parse_obj parsed_model = MyModel.model_validate(doc) print(parsed_model._creation_time)
内容的提问来源于stack exchange,提问作者Nir Brachel
相关产品推荐
相关产品推荐

