Pydantic 依赖模式

问题描述 投票:0回答:1
class LocationRequest(BaseModel):
    business_unit: Optional[str] = None
    opening: Optional[int]
    max_applicant: Optional[int]
    diversity_male: Optional[int]
    diversity_female: Optional[int]


class JobRoleRequest(BaseModel):
    name: str
    description: Optional[str] = None
    work_mode: Literal["full time", "half day"]


class JobRoleCreateRequest(JobRoleRequest):

    location: List[LocationRequest]

在子架构位置为整数字段添加空值时:

 List[LocationRequest]
但是对于business_unit,当我离开时它正在工作

需要可能的方法来为子模式字段添加空值

示例请求架构

{
    "name": "Job role",
    "description": "job role description",
    "work_mode": "Remote",
    "location": [
        {
            "business_unit": "busiess_unit of company 1",
            "opening": 10,
            "max_applicant": 4,
            "diversity_male": 2
            "diversity_female": 2,
        }
    ]
}

如果我传递的位置列表没有诸如 max_applicant 或多样性_男性之类的可选字段,那么它应该可以工作。但是,当我尝试在没有这些字段的情况下传递它时,我收到错误。

python python-3.x schema fastapi pydantic
1个回答
0
投票

您可以查看 pydantic 的文档:必填、可选和可为空字段

非必填、可为空的字段

如果您想将字段定义为非必需的可为空字段,您只需设置一个默认值即可:

max_applicant: Optional[int] = None

如果不通知现场:

sample = {
    "name": "Job role",
    "description": "job role description",
    "work_mode": "half day",
    "location": [
        {
            "business_unit": "busiess_unit of company 1",
            "opening": 10,
            "diversity_male": 2,
            "diversity_female": 2
        }
    ]
}

print(JobRoleCreateRequest(**sample))
# name='Job role' description='job role description' work_mode='half day' location=[LocationRequest(business_unit='busiess_unit of company 1', opening=10, max_applicant=None, diversity_male=2, diversity_female=2)]

您将获得

max_applicant
的默认值。

如果您在

"max_applicant": null
中通过了
json
,同样适用。

请注意,这(从您的评论中得到)是相同的:

opening: Optional[int] = Field(0, ge=0, le=999)

Optional[int] = Field(0)
表示该字段是可选的,如果不存在,则默认值为 0,但如果传递,则可以是整数或 null。

必填,但可以为空

这正是您定义字段的方式。当你将一个字段定义为可选字段,但没有给出默认值时,你就是在向 pydantic 说,创建模型时该字段是必需的,但如果该字段的值为

None
,那就可以了:

sample = {
    "name": "Job role",
    "description": "job role description",
    "work_mode": "half day",
    "location": [
        {
            "business_unit": "busiess_unit of company 1",
            "opening": None, # still required to inform, but can be null
            "max_applicant": None, # still required to inform, but can be null
            "diversity_male": None, # still required to inform, but can be null
            "diversity_female": None # still required to inform, but can be null
        }
    ]
}

print(JobRoleCreateRequest(**sample))
# name='Job role' description='job role description' work_mode='half day' location=[LocationRequest(business_unit='busiess_unit of company 1', max_applicant=None, opening=None, diversity_male=None, diversity_female=None)]

可选,但不可为空

如果你希望你的字段是可选的,但不能为空,你可以将其定义为:

opening: int = Field(ge=0, le=999, default=0)

这样,你就告诉 pydantic

opening
字段不需要被通知,如果它不存在,它将有默认值 0,但如果它存在,它需要是一个不可为空的整数。

非必需,可为空但具有不可为空的默认值

如果您希望字段是可选的,可以传递 null 值,但如果传递 null 则具有不可为 null 的值,您可以使用

field_validator
:

opening: Optional[int] = Field(0, ge=0, le=999)

@field_validator("opening")
@classmethod
def assign_default_if_none(cls, v: Optional[int]) -> int:
    return v or 0 # return your default value here

这样,如果你的payload有

"opening": None
,opening将不再为空,它将被分配默认值,或者在这种情况下为0:

class LocationRequest(BaseModel):
    business_unit: Optional[str] = None
    max_applicant: Optional[int]
    opening: Optional[int] = Field(0, ge=0, le=999)
    diversity_male: Optional[int]
    diversity_female: Optional[int]

    @field_validator("opening")
    @classmethod
    def assign_default_if_none(cls, v: Optional[int]) -> int:
        return v or 0


class JobRoleRequest(BaseModel):
    name: str
    description: Optional[str] = None
    work_mode: Literal["full time", "half day"]


class JobRoleCreateRequest(JobRoleRequest):

    location: List[LocationRequest]


sample = {
    "name": "Job role",
    "description": "job role description",
    "work_mode": "half day",
    "location": [
        {
            "business_unit": "busiess_unit of company 1",
            "opening": None,
            "max_applicant": None,
            "diversity_male": None,
            "diversity_female": None
        }
    ]
}

print(JobRoleCreateRequest(**sample))
# name='Job role' description='job role description' work_mode='half day' location=[LocationRequest(business_unit='busiess_unit of company 1', max_applicant=None, opening=0, diversity_male=None, diversity_female=None)

观察

Obs:在您的示例有效负载中,您传递的是

"work_mode": "Remote"
,而
work_mode
只能是
"full time"
"half day"

© www.soinside.com 2019 - 2024. All rights reserved.