Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以覆盖Pydantic父模型中的字段以使其成为可选字段吗?_Python_Fastapi_Pydantic - Fatal编程技术网

Python 我可以覆盖Pydantic父模型中的字段以使其成为可选字段吗?

Python 我可以覆盖Pydantic父模型中的字段以使其成为可选字段吗?,python,fastapi,pydantic,Python,Fastapi,Pydantic,我有两个像这样的pydantic类 class Parent(BaseModel): id: int name: str email: str class ParentUpdate(BaseModel): id: Optional[int] name: Optional[str] email: Optional[str] 这两个字段实际上是相同的,但父类使所有字段都是必需的。 我想在FastAPI中为POST请求主体使用Parent类,因此所有

我有两个像这样的pydantic类

class Parent(BaseModel):
    id: int
    name: str
    email: str

class ParentUpdate(BaseModel):
    id: Optional[int]
    name: Optional[str]
    email: Optional[str]
这两个字段实际上是相同的,但父类使所有字段都是必需的。 我想在FastAPI中为POST请求主体使用
Parent
类,因此所有字段都是必需的。但我想将后者用于PUT请求主体,因为用户可以设置选择性字段,其余字段保持不变。 我看了一下,但它们与我想做的不一致

如果有办法,我可以继承
ParentUpdate
中的
Parent
类,并修改
Parent
中的所有字段,使它们成为
可选的
,从而减少混乱。此外,
Parent
类中存在一些验证器,我必须在
ParentUpdate
类中重写这些验证器,这也是我想要避免的


有没有办法做到这一点?谢谢。

您可以在子类中设置必填字段,但不能在子类中设置必填字段。在fastapi作者tiangolo的样板项目中,他在您的示例中使用了如下模式:

class ParentBase(BaseModel):
    """Shared properties."""
    name: str
    email: str

class ParentCreate(ParentBase):
    """Properties to receive on item creation."""
    # dont need id here if your db autocreates it
    pass

class ParentUpdate(ParentBase):
    """Properties to receive on item update."""
    # dont need id as you are likely PUTing to /parents/{id}
    # other fields should not be optional in a PUT
    # maybe what you are wanting is a PATCH schema?
    pass

class ParentInDBBase(ParentBase):
    """Properties shared by models stored in DB - !exposed in create/update."""
    # primary key exists in db, but not in base/create/update
    id: int                             

class Parent(ParentInDBBase):
    """Properties to return to client."""
    # optionally include things like relationships returned to consumer
    # related_things: List[Thing]
    pass

class ParentInDB(ParentInDBBase):
    """Additional properties stored in DB."""
    # could be secure things like passwords?
    pass
是的,我同意这是难以置信的冗长,我希望它不是。您仍然可能会得到其他模式,这些模式更特定于UI中的特定表单。显然,您可以删除其中一些字段,因为在本例中它们不是必需的,但根据数据库中的其他字段,它们可能是必需的,或者您可能需要设置默认值、验证等

根据我对验证器的经验,您必须重新声明它们,但您可以使用共享函数,即:

def clean_article_url(cls, v):
    return clean_context_url(v.strip())

class MyModel(BaseModel):
    article_url: str

    _clean_url = pydantic.validator("article_url", allow_reuse=True)(clean_article_url)

我事先表示歉意,我肯定这是一个非常糟糕的解决办法,但它对我很有效:

def使子字段可选(父类:类型[BaseModel],子类:类型[BaseModel]):
对于父类中的键。\u\u字段\u\u:
子类.字段.获取(键).required=False
class BasePerson(基本模型):
姓名:str
电邮:str
登录名:str
类更新人员(BasePerson):
通过什么
使子字段可选(BasePerson、UpdatePerson)

我的建议是不要发明困难的模式,我也对pydantic功能感兴趣,但它们看起来都很难看,很难理解(甚至不适用于某些任务,并且有限制)。 看见
pydantic维护人员的回答

正如对类似问题的回答中所述,我使用以下方法(归功于Aron Podrigal):

在您的示例中,您可以这样使用它:

@optional
class ParentUpdate(Parent):
    pass
@optional
class ParentUpdate(Parent):
    pass