使用 Fastapi 的 class 变量更改 pydantic 模型 Field() 参数
Changing pydantic model Field() arguments with class variables for Fastapi
我对 python 中的 class 继承有点陌生,尤其是当涉及到使用 class 属性时。在这种情况下,我使用 class 属性 来更改 pydantic 的 Field()
函数中的参数。如果我的 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)
创建实例时,我希望抛出验证错误,但它却通过了验证,只是 returns item
值。
如果我有自己的构造函数,那么更改 _set_ge
不会有什么问题,但是由于 User1
从 BaseModel
继承了这个构造函数,事情就有点复杂了。
最终目标是将此 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()
参数。如果有更好的方法,我也很乐意考虑。
此问题与 this 未回答的问题密切相关。
最后,@hernán-alarcón 提出的 @validator
提议可能是最好的方法。例如:
from pydantic import Basemodel, Field, NumberNotGeError
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
我对 python 中的 class 继承有点陌生,尤其是当涉及到使用 class 属性时。在这种情况下,我使用 class 属性 来更改 pydantic 的 Field()
函数中的参数。如果我的 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)
创建实例时,我希望抛出验证错误,但它却通过了验证,只是 returns item
值。
如果我有自己的构造函数,那么更改 _set_ge
不会有什么问题,但是由于 User1
从 BaseModel
继承了这个构造函数,事情就有点复杂了。
最终目标是将此 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()
参数。如果有更好的方法,我也很乐意考虑。
此问题与 this 未回答的问题密切相关。
最后,@hernán-alarcón 提出的 @validator
提议可能是最好的方法。例如:
from pydantic import Basemodel, Field, NumberNotGeError
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