如何将组装字段添加到 Pydantic 模型

Posted

技术标签:

【中文标题】如何将组装字段添加到 Pydantic 模型【英文标题】:How do add an assembled field to a Pydantic model 【发布时间】:2020-12-09 00:37:15 【问题描述】:

说我有模特

class UserDB(BaseModel):
    first_name: Optional[str] = None
    last_name: Optional[str] = None

如何制作另一个模型,该模型是从这个模型构建的,并且其字段会根据该模型中的字段而变化?

比如这样的

class User(BaseModel):
    full_name: str = first_name + ' ' + last_name

可能是这样构造的

User.parse_obj(UserDB)

谢谢!

【问题讨论】:

【参考方案1】:

如果您不想在User 中保留first_namelast_name,那么您可以

自定义__init__。 使用验证器设置full_name

这两种方法都可以做你想做的事:

from typing import Optional
from pydantic import BaseModel, validator


class UserDB(BaseModel):
    first_name: Optional[str] = None
    last_name: Optional[str] = None


class User_1(BaseModel):
    location: str  # for a change
    full_name: Optional[str] = None

    def __init__(self, user_db: UserDB, **data):
        super().__init__(full_name=f"user_db.first_name user_db.last_name", **data)


user_db = UserDB(first_name="John", last_name="Stark")
user = User_1(user_db, location="Mars")
print(user)


class User_2(BaseModel):
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    full_name: Optional[str] = None

    @validator('full_name', always=True)
    def ab(cls, v, values) -> str:
        return f"values['first_name'] values['last_name']"


user = User_2(**user_db.dict())
print(user)

输出

location='Mars' full_name='John Stark'
first_name='John' last_name='Stark' full_name='John Stark'

更新: 要使用response_model,您可以通过以下方式自定义__init__

class User_1(BaseModel):
    location: str  # for a change
    full_name: Optional[str] = None

    # def __init__(self, user_db: UserDB, **data):
    def __init__(self, first_name, last_name, **data):
        super().__init__(full_name=f"first_name last_name", **data)


user_db = UserDB(first_name="John", last_name="Stark")
user = User_1(**user_db.dict(), location="Mars")
print(user)

【讨论】:

这在正常情况下有效,谢谢!对于奖励积分,您是否知道如何让它与 fastapi response_model 一起使用?如果我只是返回将响应模型设置为 api 模型的 db 模型,它会抛出 pydantic.error_wrappers.ValidationError: 1 validation error for User response __init__() missing 1 required positional argument: 'user_db' (type=type_error) 我在我的项目中使用了第二种方法,但我一直觉得使用验证器来设置属性似乎......很脏。我也尝试添加@property,但随后它被排除在.dict() 方法中

以上是关于如何将组装字段添加到 Pydantic 模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 pydantic 模型中解析 ObjectId?

如何给 Pydantic 列表字段一个默认值?

您将如何使用带有 FastAPI 的 asyncpg 将选择查询的返回值映射到 pydantic 模型以进行输出和验证?

如何在 pydantic 中设置最大字符串字段长度约束?

如何组装6根孔明锁?

pydantic.BaseModel:父类的类方法