我正在制作一个带有端点的API,它应该返回一个像这样的对象
{
'id': 'asdqwe123randomnessxxyyzz',
'title': 'some title',
'owner': {
'id': 'qwersdaf4132otherrandomness',
'name': 'some name',
},
}
,在数据库中对象看起来像这样
{
'id': 'asdqwe123randomnessxxyyzz',
'title': 'some title',
'owner_id': 'qwersdaf4132otherrandomness',
}
我正在为我的API使用pydantic模型,目前我正在返回这样的对象
return [Object(**x) for x in mongo_db_column.find()]
其中x
是来自数据库的json
Object的类是这样的:
from pydantic import Basemodel, Optional
class Object(Basemodel):
id: Optional[str]
title: str
owner_id: str
和所有者类看起来像这样:
class Owner(Basemodel):
id: Optional[str]
name: str
所以我的问题是,如果有可能使用Basemodel
的一些方法来实例化它,以便owner_id
将转换为Owner
的实例?
至少有两种方法可以达到你的目标。
首先是保持pydantic模型"哑巴";(意味着它们不以任何方式绑定到数据库),并使用数据库中已经聚合的数据初始化它们。
您将不得不重写您的模型,以便Object
模型引用Owner
。
from typing import Optional
from pydantic import BaseModel
class Owner(BaseModel):
id: Optional[str]
name: str
class Object(BaseModel):
id: Optional[str]
title: str
owner: Owner
如果你已经汇总了数据,那么:
data = {
'id': 'asdqwe123randomnessxxyyzz',
'title': 'some title',
'owner': {
'id': 'qwersdaf4132otherrandomness',
'name': 'some name',
},
}
Object(**data) # this would produce desired value
您也可以从Basemodel字段的预验证中加载引用的所有者:
from typing import Optional
from pydantic import BaseModel, Field, validator
class Owner(BaseModel):
id: Optional[str]
name: str
class Object(BaseModel):
id: Optional[str]
title: str
owner: Owner = Field(..., alias='owner_id')
@validator('owner', pre=True)
def load_owner(cls, owner_id):
if isinstance(owner_id, str):
# perform loading from owner collection
# e.g. owner = owner_collection.find_one({'id': owner_id})
return owner
return owner_id
这样你的代码应该产生期望的值。