You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:17:28