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

如何使用Pydantic验证包含内部JSON字符串的JSON数据?

问题说明

API接收到的JSON字符串中,inner_data字段是JSON格式的字符串(而非直接的JSON对象):

{"data": 123, "inner_data": "{\"color\": \"RED\"}"}

按常规方式定义Pydantic模型(将inner_data声明为InnerData类型)后,调用model_validate_json会触发验证错误:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Expected
inner_data
  Input should be an object [type=model_type, input_value='{"color": "RED"}', input_type=str]

原因是Pydantic默认期望inner_data是JSON对象,而非字符串类型的JSON结构。

解决方案

以下三种方法可解决该问题:

方法1:使用前置验证器解析JSON字符串

通过BeforeValidator添加前置处理逻辑,先将inner_data的字符串解析为JSON对象,再交由InnerData模型验证:

from pydantic import BaseModel, BeforeValidator
from typing import Any
import json

def parse_json_str(v: Any) -> Any:
    if isinstance(v, str):
        return json.loads(v)
    return v

class InnerData(BaseModel):
    color: str

class Expected(BaseModel):
    data: int
    inner_data: InnerData = BeforeValidator(parse_json_str)

# 验证示例
incoming_json_string = '{"data": 123, "inner_data": "{\"color\": \"RED\"}"}'
expected = Expected.model_validate_json(incoming_json_string)

方法2:封装解析逻辑到内层模型

自定义模型的核心验证逻辑,让InnerData自动处理字符串类型的输入:

from pydantic import BaseModel, GetJsonSchemaHandler
from pydantic_core import core_schema
from typing import Any, Type
import json

class JsonStringParsableModel(BaseModel):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type: Type[Any], handler: GetJsonSchemaHandler) -> core_schema.CoreSchema:
        def validate(value: Any) -> Any:
            if isinstance(value, str):
                value = json.loads(value)
            return cls(**value)
        
        return core_schema.no_info_plain_validator_function(
            validate,
            json_schema=handler(cls),
        )

class InnerData(JsonStringParsableModel):
    color: str

class Expected(BaseModel):
    data: int
    inner_data: InnerData

# 验证示例
incoming_json_string = '{"data": 123, "inner_data": "{\"color\": \"RED\"}"}'
expected = Expected.model_validate_json(incoming_json_string)

方法3:手动分步解析JSON

先解析外层JSON,再手动处理inner_data字段的字符串解析,最后传入模型验证:

import json
from pydantic import BaseModel

class InnerData(BaseModel):
    color: str

class Expected(BaseModel):
    data: int
    inner_data: InnerData

# 验证示例
incoming_json_string = '{"data": 123, "inner_data": "{\"color\": \"RED\"}"}'
outer_dict = json.loads(incoming_json_string)
outer_dict["inner_data"] = json.loads(outer_dict["inner_data"])
expected = Expected(**outer_dict)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:23:23