【问题标题】:How do add an assembled field to a Pydantic model如何将组装字段添加到 Pydantic 模型
【发布时间】: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)

谢谢!

【问题讨论】:

    标签: python fastapi pydantic


    【解决方案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() 方法中
    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2018-11-01
    • 2021-04-05
    • 1970-01-01
    相关资源
    最近更新 更多