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

Pydantic拒绝识别已注解自定义模型,如何将其用作字段类型?

解决Pydantic中自定义类作为字段类型的注解报错问题

正确实现代码示例

假设你使用的是Pydantic 2.x,先确保自定义模型CurrencyCode的写法符合规范,再在MyTestModel中正确引用:

from pydantic import RootModel, Field, model_validator, BaseModel
from typing import Annotated

# 自定义基类TripleApiModel示例(包含通用验证逻辑)
class TripleApiModel:
    @model_validator(mode='before')
    def common_validation(cls, values):
        # 这里编写通用校验逻辑,比如统一格式检查
        return values

# 正确定义CurrencyCode:继承自定义基类 + RootModel[str]
class CurrencyCode(TripleApiModel, RootModel[str]):
    # 用Annotated给root字段添加约束规则
    root: Annotated[str, Field(min_length=3, max_length=3, pattern=r'^[A-Z]{3}$')]

    # 可选:自定义货币代码专属验证
    @model_validator(mode='after')
    def validate_currency(cls, value):
        valid_codes = {'USD', 'EUR', 'CNY', 'GBP'}
        if value.root not in valid_codes:
            raise ValueError(f"无效货币代码:{value.root},需为ISO 4217标准3位大写字母")
        return value

# 在MyTestModel中直接将CurrencyCode作为字段类型
class MyTestModel(BaseModel):
    currency_code: CurrencyCode
    amount: float

验证测试

实例化时可直接传入字符串,Pydantic会自动解析为CurrencyCode对象:

# 合法数据场景
valid_data = MyTestModel(currency_code='USD', amount=150.5)
print(valid_data.currency_code.root)  # 输出: USD
print(valid_data.model_dump())        # 输出: {'currency_code': 'USD', 'amount': 150.5}

# 非法数据触发验证报错
try:
    invalid_data = MyTestModel(currency_code='US', amount=100)
except Exception as e:
    print(e)  # 提示字符串长度不符合要求

排查可能踩的坑

  1. 继承顺序错误:确保继承列表中包含Pydantic的模型基类(如RootModel[str]),自定义基类放在前面不影响,但不能遗漏Pydantic的模型类。
  2. Annotated使用位置错误:不要把Annotated加在类定义上,必须加在RootModel要求的root字段上。
  3. Pydantic版本不兼容:RootModel是Pydantic 2.x新增特性,若使用1.x版本,需改用BaseModel并定义__root__字段:
    # Pydantic 1.x写法
    from pydantic import BaseModel
    class CurrencyCode(TripleApiModel, BaseModel):
        __root__: Annotated[str, Field(...)])
    
  4. 自定义基类冲突:如果TripleApiModel有自定义__init__方法,可能干扰Pydantic的模型初始化,建议改用model_validator或field_validator实现通用逻辑。
  5. 字段引用冗余包装:在MyTestModel中直接写currency_code: CurrencyCode即可,无需额外套Annotated(除非需要给该字段加描述、默认值等元数据,此时可写Annotated[CurrencyCode, Field(description="...")])。

内容的提问来源于stack exchange,提问作者Jelkimantis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:42:37