
本文详解 Pydantic 内置的 JsonValue 类型,帮助开发者精准校验符合 JSON 序列化规范的嵌套数据(如字典、列表、基础类型等),避免手动定义递归类型引发的报错,并确保字段值可无损转为标准 JSON。
本文详解 pydantic 内置的 `jsonvalue` 类型,帮助开发者精准校验符合 json 序列化规范的嵌套数据(如字典、列表、基础类型等),避免手动定义递归类型引发的报错,并确保字段值可无损转为标准 json。
在使用 Pydantic 构建 API 请求/响应模型时,常需约束某个字段为「合法的 JSON 值」——即该值必须能被 json.dumps() 无异常序列化。例如,接收前端传来的动态配置对象、嵌套元数据或通用 payload,要求其结构严格限定于 JSON 支持的类型:str、int、float、bool、None、list(元素也为 JSON 值)、dict(键为 str,值为 JSON 值)。
直接使用 Dict[str, Any] 风险极高:它允许 datetime、UUID、自定义类等非 JSON 可序列化类型通过校验,后续调用 json.dumps() 会抛出 TypeError;而 pydantic.Json 仅校验JSON 字符串格式(如 '{"a": 1}'),不适用于已解析的 Python 对象。
Pydantic v2+ 提供了开箱即用的解决方案:JsonValue —— 一个专为 JSON 兼容性设计的递归联合类型。其定义如下:
from pydantic.types import JsonValue # 等价于: # JsonValue = Union[ # List["JsonValue"], # Dict[str, "JsonValue"], # str, # bool, # int, # float, # None, # ]
✅ 正确用法示例:
from pydantic import BaseModel, ValidationError
from pydantic.types import JsonValue
class ConfigModel(BaseModel):
metadata: JsonValue # 接受任意 JSON 兼容结构
options: dict[str, JsonValue] # 显式要求字典,且值为 JSON 兼容
# 合法输入(均可被 json.dumps() 处理)
valid_data = {
"metadata": {
"tags": ["prod", "v2"],
"timeout": 30.5,
"enabled": True,
"config": {"retry": 3, "backoff": "exponential"},
"notes": None
},
"options": {"theme": "dark", "auto_save": False}
}
model = ConfigModel(**valid_data)
print(model.model_dump_json(indent=2))
# 输出为标准 JSON 字符串,无类型错误❌ 校验失败示例(将触发 ValidationError):
# 包含非 JSON 类型 → 校验失败
invalid_data = {
"metadata": {"created_at": datetime.now()}, # datetime 不在 JsonValue 中
"options": {"id": uuid4()} # UUID 同样不支持
}
try:
ConfigModel(**invalid_data)
except ValidationError as e:
print(e)
# Error: 2 validation errors for ConfigModel
# metadata -> created_at
# Input should be a valid string, number, boolean, None, list or dict [type=union_tag_invalid, ...]⚠️ 注意事项:
- JsonValue 不校验字典键的类型(仅保证值合法),但 JSON 规范要求键必须为字符串。因此若需强约束键为 str,应显式使用 Dict[str, JsonValue] 或 dict[str, JsonValue](推荐后者,语义更清晰);
- JsonValue 是 运行时类型提示,不参与静态类型检查(如 mypy),如需完整类型安全,可配合 typing.cast 或自定义类型别名辅助;
- 若字段必须是 JSON 对象(即 dict),而非任意 JSON 值,请勿直接注解为 JsonValue,而应使用 dict[str, JsonValue],以排除 str/list/None 等非法顶层类型;
- 在 Pydantic v1 中无原生 JsonValue,需手动定义带前向引用的递归类型(易出错),升级至 v2 是最佳实践。
总结:JsonValue 是 Pydantic 对 JSON 数据建模的“黄金标准”——它既保证了类型安全与运行时校验,又完全对齐 JSON 规范。合理使用该类型,可显著提升 API 数据契约的健壮性,杜绝因类型失控导致的序列化崩溃。










