我有两个这样的pydantic类。
class Parent(BaseModel):
id: int
name: str
email: str
class ParentUpdate(BaseModel):
id: Optional[int]
name: Optional[str]
email: Optional[str]
这两个类实际上是相同的,但Parent
类使所有字段都是必需的。我想在FastAPI中使用Parent
类作为POST请求体,因此所有字段都应该是必需的。但是我想使用后者作为PUT请求体,因为用户可以设置选择性字段,其余字段保持不变。我已经看了一下必填的可选字段,但它们与我想做的不对应。
如果有一种方法,我可以继承ParentUpdate
中的Parent
类,并修改Parent
中的所有字段,使它们成为Optional
,这将减少混乱。另外,在Parent
类中有一些验证器,我必须在ParentUpdate
类中重写,这也是我想避免的。
有什么办法可以做到这一点吗?
7条答案
按热度按时间vql8enpb1#
可以在子类中将可选字段设为必填字段,但不能在子类中将必填字段设为可选字段。在fastapi作者tiangolo的样板项目中,他在示例中使用了这样的模式:
是的,我同意这是令人难以置信的冗长,我希望它不是。您仍然可能会在UI中使用更特定于特定表单的其他模式。显然,您可以删除其中的一些,因为它们在本例中是不必要的,但根据数据库中的其他字段,它们可能是需要的,或者您可能需要设置默认值、验证等。
根据我对验证器的经验,你必须重新声明它们,但你可以使用一个共享函数,即:
zazmityj2#
覆盖字段是可能且容易的。(有人提到不可能将必填字段覆盖为可选字段,但我不同意)。
这个例子没有任何问题:
xmakbtuz3#
我的建议是不要发明困难的模式,我也对pydantic功能感兴趣,但所有这些功能看起来都很难看,很难理解(甚至不适合某些任务,并且有限制)。参见pydantic维护者的Python pydantic, make every field of ancestor are Optional答案
fruv7luv4#
正如在回答类似问题时所概述的那样,我使用以下方法(归功于Aron Podrigal):
在你的例子中,你会这样使用它:
kqlmhetl5#
我提前道歉,我肯定这是一个可怕的解决方案,但它对我有效:
fdbelqdn6#
对于我的情况,创建一个新类是唯一有效的解决方案,但打包到一个函数中非常方便:
对比之前和之后:
它确实有效,而且如果需要的话,它还允许你过滤掉类的一些字段。
此外,对于FastApi,您可以直接使用make_optional(Parent)作为API调用中的类型提示,这将正确生成文档。这种方法的另一个优点是它可以大大减少样板文件。
g0czyy6m7#
如果你想只覆盖一些给定的字段,而不重复类型提示,你可以使用这样的装饰器来实现:
根据文档,
__fields__
是一个模型属性,它可以用来通过名称访问模型的字段并修改它们的属性。应用装饰器,其中包含您希望设置为可选的字段的名称: