如何让Pydantic依据type字段正确解析多类型服务模型?
解决Pydantic基于type字段区分模型的解析问题
问题场景
我定义了如下Pydantic模型:
import datetime import pydantic class MealsService(pydantic.BaseModel): class MealItem(pydantic.BaseModel): course: str name: str quantity: int unitPrice: float | None type: str = "meals" items: list[MealItem] time: datetime.time | None class CanapesService(pydantic.BaseModel): class CanapeItem(pydantic.BaseModel): name: str quantity: int unitPrice: float | None type: str = "canapes" items: list[CanapeItem] time: datetime.time | None class Event: services: list[MealsService | CanapesService]
给定以下JSON负载:
{ "services": [ { "type": "canapes", "items": [], "time": null } ] }
Pydantic错误地将其解析为MealsService实例而非CanapesService,原因是当嵌套字段为空时两个模型结构一致。需要实现基于type字段("meals"或"canapes")的精确匹配来正确解析。
解决方案:使用Pydantic鉴别器(discriminator)
Pydantic支持通过鉴别器指定字段来区分联合类型模型,确保解析时严格匹配type字段的值。
1. 修正Event模型
将Event改为继承pydantic.BaseModel,并为services字段添加鉴别器配置,明确指定用type字段区分模型:
import datetime import pydantic class MealsService(pydantic.BaseModel): class MealItem(pydantic.BaseModel): course: str name: str quantity: int unitPrice: float | None type: str = "meals" items: list[MealItem] time: datetime.time | None class CanapesService(pydantic.BaseModel): class CanapeItem(pydantic.BaseModel): name: str quantity: int unitPrice: float | None type: str = "canapes" items: list[CanapeItem] time: datetime.time | None class Event(pydantic.BaseModel): # 用discriminator指定type字段作为模型区分依据 services: list[MealsService | CanapesService] = pydantic.Field(..., discriminator="type")
2. 验证解析结果
运行测试代码验证:
json_payload = { "services": [ { "type": "canapes", "items": [], "time": None } ] } event = Event.model_validate(json_payload) print(type(event.services[0])) # 输出:<class '__main__.CanapesService'>
核心原理
- 鉴别器会强制Pydantic检查
type字段的值,严格匹配对应模型的默认值 - 即使嵌套字段为空,只要
type字段匹配,就会正确选择目标模型 - 如果
type字段值不在预期范围内,Pydantic会直接抛出验证错误
内容的提问来源于stack exchange,提问作者Inigo Selwood
相关产品推荐
相关产品推荐

