如何用Pydantic BaseModel将owner_id转换为对应的Owner实例引用
可以实现,你可以通过Pydantic提供的实例化后钩子方法model_post_init(V2版本)或者属性装饰器实现,不需要大幅修改现有代码,具体方案如下:
前提说明
由于你存储的Object数据只有owner_id,没有Owner的其他字段,需要先在接口层批量查询关联的Owner数据,避免单次查询的N+1性能问题。
步骤1:修正拼写错误
你现有代码中的Basemodel拼写错误,正确写法是BaseModel(B和M都大写)。
步骤2:调整接口逻辑
先批量查询Owner数据构建映射,再实例化Object模型:
# 查询所有需要返回的Object数据 db_objects = list(mongo_db_column.find()) # 提取所有关联的owner_id,批量查询Owner数据 all_owner_ids = [obj["owner_id"] for obj in db_objects] db_owners = list(owner_collection.find({"id": {"$in": all_owner_ids}})) # 构建owner_id到Owner实例的映射字典 owner_map = {owner["id"]: Owner(**owner) for owner in db_owners} # 实例化Object模型时传入映射字典即可,原有逻辑改动极小 return [Object(**obj, owner_map=owner_map) for obj in db_objects]
步骤3:改造Object模型
如果你使用的是Pydantic V2(当前主流版本)
from pydantic import BaseModel, Optional, Field class Owner(BaseModel): id: Optional[str] name: str class Object(BaseModel): id: Optional[str] title: str owner_id: str # owner_map设为排除字段,序列化返回时不会输出该字段 owner_map: dict[str, Owner] = Field(exclude=True) owner: Owner = None def model_post_init(self, __context) -> None: # 实例化完成后自动赋值owner字段 self.owner = self.owner_map[self.owner_id]
如果你使用的是Pydantic V1版本
from pydantic import BaseModel, Optional, Field class Object(BaseModel): id: Optional[str] title: str owner_id: str owner_map: dict[str, Owner] = Field(exclude=True) @property def owner(self) -> Owner: return self.owner_map[self.owner_id] class Config: orm_mode = True
序列化返回时调用object.dict(include={"id", "title", "owner"})即可得到你需要的目标格式。
内容的提问来源于stack exchange,提问作者mama
相关产品推荐
相关产品推荐

