将对象属性从 id 更改为实际 id 引用的好方法是什么

What is a good way to mutate object attribute from id to actual id reference

我正在制作一个 API 端点,它应该 return 一个像这样的对象

{
'id': 'asdqwe123randomnessxxyyzz',
'title': 'some title',
'owner': {
    'id': 'qwersdaf4132otherrandomness',
    'name': 'some name',
    },
}

在数据库中对象看起来像这样

{
'id': 'asdqwe123randomnessxxyyzz',
'title': 'some title',
'owner_id': 'qwersdaf4132otherrandomness',
}

我正在为我的 API 使用 pydantic 模型,目前我正在 return 像这样

return [Object(**x) for x in mongo_db_column.find()]

其中 x 是数据库中的 json

对象的 class 看起来像这样:

from pydantic import Basemodel, Optional

class Object(Basemodel):
    id: Optional[str]
    title: str
    owner_id: str

而所有者 class 看起来像这样:

class Owner(Basemodel):
    id: Optional[str]
    name: str

所以我的问题是是否可以使用 Basemodel 中的某些方法来实例化它,以便将 owner_id 转换为 Owner 的实例?

至少有 2 种方法可以实现您的目标。

首先是保持 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

这样您的代码应该会产生所需的值。