Pydantic v2模型如何根据API场景设置条件必填属性?
在Pydantic v2中实现字段的条件必填
你当前的场景是:InvoiceItem模型所有字段设为可选,用于解析带查询参数的API响应(参数会控制返回值范围);但通过API创建对象时,部分字段需要设为必填。以下是两种可行的实现方式:
方案一:继承基类并覆盖字段必填性
直接创建继承自InvoiceItem的专属模型,无需重复定义所有字段,仅重新声明需要设为必填的字段即可:
from pydantic import BaseModel, PositiveInt, AnyHttpUrl class InvoiceItem(BaseModel): """用于解析API响应的模型,所有字段可选""" id: PositiveInt | None = None org: AnyHttpUrl | None = None relatedInvoice: AnyHttpUrl | None = None quantity: PositiveInt | None = None class InvoiceItemCreate(InvoiceItem): """用于创建对象的模型,指定必填字段""" org: AnyHttpUrl quantity: PositiveInt
InvoiceItemCreate会继承基类的所有字段,但org和quantity被覆盖为必填属性,其余字段保持原有可选状态(若有需要也可调整其他字段的必填性)。
方案二:参数化模型(动态控制字段必填性)
如果需要根据外部场景动态切换字段的必填规则,可以通过以下两种方式实现:
方式1:结合字段验证器与上下文参数
from pydantic import BaseModel, PositiveInt, AnyHttpUrl, field_validator, ValidationInfo class InvoiceItem(BaseModel): id: PositiveInt | None = None org: AnyHttpUrl | None = None relatedInvoice: AnyHttpUrl | None = None quantity: PositiveInt | None = None model_config = {"extra": "forbid"} @field_validator("org", "quantity") def check_required_fields(cls, value, info: ValidationInfo): # 通过上下文参数判断是否为创建场景 if info.context.get("is_create", False) and value is None: raise ValueError("此字段为必填项") return value
使用时通过传入context参数切换验证规则:
# 解析API响应时,不启用必填验证 response_invoice = InvoiceItem(**{"id": 123}) # 创建对象时,启用必填验证 create_invoice = InvoiceItem(**{"org": "https://example.org", "quantity": 5}, context={"is_create": True})
方式2:动态生成模型
利用pydantic.create_model根据场景动态生成对应模型:
from pydantic import create_model # 基于基类动态生成创建用模型 InvoiceItemCreate = create_model( "InvoiceItemCreate", __base__=InvoiceItem, org=(AnyHttpUrl, ...), # 覆盖为必填 quantity=(PositiveInt, ...), # 覆盖为必填 )
这种方式适合需要灵活生成多场景模型的需求。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

