
本文介绍如何使用 Pydantic 内置的 JsonValue 类型(v2.0+)安全、高效地校验任意层级嵌套的 JSON 兼容数据(如字典、列表、字符串、数字、布尔值或 None),避免递归类型定义错误,并确保值可无损序列化为标准 JSON。
本文介绍如何使用 pydantic 内置的 `jsonvalue` 类型(v2.0+)安全、高效地校验任意层级嵌套的 json 兼容数据(如字典、列表、字符串、数字、布尔值或 none),避免递归类型定义错误,并确保值可无损序列化为标准 json。
在构建 API 或处理外部输入时,我们常需确保某个字段是「真正可 JSON 序列化的数据」——即它必须能被 json.dumps() 无异常地转换为 JSON 字符串。虽然 Dict[str, Any] 看似可用,但它允许 datetime、UUID、自定义对象等非 JSON 原生类型,导致后续序列化失败;而 pydantic.Json 仅用于解析 JSON 字符串(如 '"hello"' → "hello"),不适用于已解析的 Python 数据结构。
Pydantic v2 起提供了开箱即用的 JsonValue 类型,专为此场景设计。它是一个严格受限的联合类型,精确对应 JSON 规范支持的 7 种原子与复合值:
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
from pydantic import BaseModel, JsonValue
from typing import Dict, List
# ✅ 正确:直接校验任意 JSON 兼容值
class PayloadModel(BaseModel):
data: JsonValue
# ✅ 正确:若明确要求顶层为对象(即 JSON object),可限定为字典
class ObjectModel(BaseModel):
config: Dict[str, JsonValue]
# ✅ 示例:合法输入(全部可通过校验)
valid_inputs = [
{"name": "Alice", "scores": [95, 87], "active": True, "meta": None},
["a", 42, False],
"string",
3.14,
None,
]
for inp in valid_inputs:
try:
model = PayloadModel(data=inp)
print(f"✓ Valid: {inp}")
except Exception as e:
print(f"✗ Invalid: {inp} → {e}")
# ❌ 以下会校验失败(因不可 JSON 序列化)
invalid_inputs = [
{"created_at": datetime.now()}, # datetime 不在 JsonValue 中
{"id": uuid4()}, # UUID 不被允许
{"func": lambda x: x}, # 可调用对象非法
]⚠️ 注意事项:
- JsonValue 不包含 bytes、decimal.Decimal、Enum、datetime 等常见非 JSON 类型,这是其核心设计目标:保证 .model_dump_json() 或 json.dumps(model.model_dump()) 永远不会抛出 TypeError。
- 若需支持扩展类型(如 datetime 转 ISO 字符串),应配合 @field_serializer 自定义序列化逻辑,而非放宽 JsonValue 类型。
- 在 Pydantic v1 中无原生等价物,需手动定义递归类型(易出错且不推荐);升级至 v2+ 是最佳实践。
- JsonValue 是 type alias,非运行时校验器,但其类型提示会与 Pydantic 的验证逻辑深度协同,提供静态检查 + 动态校验双重保障。
总结而言,JsonValue 是校验「已解析 JSON 数据结构」的黄金标准。当你的模型字段预期接收来自 json.loads() 的结果、前端传来的原始对象/数组,或需确保下游 json.dumps() 安全时,请直接使用 JsonValue —— 简洁、准确、零配置,且完全符合 JSON 规范语义。









