簡體   English   中英

如何將組裝的字段添加到 Pydantic model

[英]How do add an assembled field to a Pydantic model

假設我有 model

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

我如何制作另一個 model,它是從這個構建的,並且有一個字段根據這個 model 中的字段而變化?

例如,像這樣的東西

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

像這樣構造也許

User.parse_obj(UserDB)

謝謝!

如果您不想在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)

output

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)

我創建了一個 pip package 似乎完全可以滿足您的需求。 這是鏈接: https://pypi.org/project/pydantic-computed/

您的示例將如下所示:

from pydantic import BaseModel
from pydantic_computed import Computed, computed

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

class User(UserDB):
    full_name: Computed[str]

    @computed('full_name')
    def compute_full_name(first_name: str, last_name: str):
        return first_name + ' ' + last_name


# parsing also works as normal:
user_db = UserDB(first_name='John', last_name='Doe')
user = User.parse_obj(user_db)
print(user.full_name) # Outputs "John Doe"

這也適用於 response_model(例如在 FastAPI 中),因為計算值實際上是在 full_name 屬性上設置的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM