【问题标题】:Changing pydantic model Field() arguments with class variables for Fastapi使用 Fastapi 的类变量更改 pydantic 模型 Field() 参数
【发布时间】:2021-11-19 01:04:30
【问题描述】:

我对在 python 中修改类继承有点陌生,尤其是涉及到使用 类属性。在这种情况下,我使用 类属性 来更改 pydantic 的 Field() 函数中的参数。如果我的类包含它自己的构造函数,这不会太难做到,但是,我的类User1 是从 pydantic 的BaseModel 继承的。 这个想法是我希望能够在创建实例之前更改 类属性

请看下面的一些示例代码:

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 继承了这个构造函数,事情就复杂了一些。

最终的目标是将此类添加到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 unanswered one 密切相关。

【问题讨论】:

  • 你为什么不使用validator?据我所知,ge(和其他)旨在用于固定值。
  • 我想过这个,它也许确实是最好的解决方案。我重用了自定义验证器来进行更复杂的验证。但是,我希望尽可能多地依赖 pydantic 的内置验证方法,同时学习更多关于将类属性与 pydantic 模型(以及 @dataclass,我认为它们具有类似行为)一起使用的知识。此外,以后我可能还想让Field()titledescription 参数也可以自定义。

标签: python validation subclass fastapi pydantic


【解决方案1】:

最后,@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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2022-06-21
    • 2020-09-28
    相关资源
    最近更新 更多