簡體   English   中英

使用 Fastapi 的 class 變量更改 pydantic model Field() arguments

[英]Changing pydantic model Field() arguments with class variables for Fastapi

我對在 python 中修補 class inheritance 有點陌生,尤其是在使用ZA2F2ED298EBC2CBBD4C21 屬性時。 在這種情況下,我使用class 屬性來更改 pydantic 的Field() function 中的參數。 如果我的 class 包含它自己的構造函數,這不會太難做到,但是,我的 class User1是從 pydantic 的BaseModel繼承的。 這個想法是我希望能夠在創建實例之前更改class 屬性

請參閱下面的一些示例代碼:

from pydantic import Basemodel, Field   

class User1(BaseModel):
    _set_ge = None # create class attribute
    item: float = Field(..., ge=_set_ge)

    # avoid overriding BaseModel's __init__
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    
User1._set_ge = 0 # setting the class attribute to a new value
instance = User1(item=-1)
print(instance) # item=-1.0

使用instance = User1(item=-1)創建實例時,我希望會引發驗證錯誤,但它會通過驗證並簡單地返回item值。

如果我有自己的構造函數,那么更改_set_ge就沒什么問題,但是由於User1BaseModel繼承了這個構造函數,事情就有點復雜了。

最終目標是將此 class 添加到fastapi端點,如下所示:

from fastapi import Fastapi
from schemas import User1    

class NewUser1(User1):
      pass

NewUser1._set_ge = 0    

@app.post("/")
def endpoint(request: NewUser1):
    return User1.item

為了減少代碼重復,我打算使用這種方法輕松更改Field() arguments。 如果有更好的方法,我也很樂意考慮。

這個問題與這個未回答的問題密切相關。

最后,@hernán-alarcón 的@validator提議可能是最好的方法。 例如:

from pydantic import Basemodel, Field
from typing import ClassVar   

class User(BaseModel):
    _set_ge = ClassVar[float] # added the ClassVar typing to make clearer, but the underscore should be sufficient
    item: float = Field(...)

    @validator('item')
    def limits(cls, v):
        limit_number = cls._set_ge
        if v >= limit_number:
            return v
        else:
            raise NumberNotGeError(limit_value=limit_number)
        
    
class User1(User)
     _set_ge = 0 # setting the class attribute to a new value

instance = User1(item=-1) # raises the error

暫無
暫無

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

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