如何自定义Pydantic模型的json()方法实现非对象类型序列化?
实现方案
完全可以实现这个需求,核心是重写Pydantic模型的序列化方法,同时添加字段验证逻辑,确保模型实例输出单个值而非JSON对象,且支持嵌套使用。
完整代码示例
from pydantic import BaseModel, StrictInt, StrictStr, root_validator from typing import Optional import json class IntOrString(BaseModel): int_value: Optional[StrictInt] = None string_value: Optional[StrictStr] = None # 验证逻辑:确保仅能设置int_value或string_value其中一个 @root_validator(pre=True) def check_single_field(cls, values): provided_fields = [k for k, v in values.items() if v is not None] if len(provided_fields) != 1: raise ValueError("必须且仅能设置int_value或string_value其中一个字段") return values # 重写model_dump,返回单个值而非字典 def model_dump(self, **kwargs): return self.int_value if self.int_value is not None else self.string_value # 重写model_dump_json,直接序列化单个值 def model_dump_json(self, **kwargs): return json.dumps(self.model_dump()) # 兼容Pydantic V1的json()方法 json = model_dump_json
测试验证
# 测试单个实例 p1 = IntOrString(int_value=123) print(p1.json()) # 输出:123 p2 = IntOrString(string_value="Hello World") print(p2.json()) # 输出:"Hello World" # 测试嵌套使用 class ParentModel(BaseModel): data: IntOrString desc: str parent = ParentModel(data=IntOrString(int_value=456), desc="嵌套测试") print(parent.json()) # 输出:{"data":456,"desc":"嵌套测试"}
关键说明
- 字段验证:通过
root_validator避免出现多值或空值的非法情况,保证模型数据的合法性。 - 序列化逻辑:
model_dump返回单个原始值,model_dump_json基于该值生成对应JSON格式字符串,既支持单独使用,嵌套到其他模型时也能自动适配父模型的序列化流程。 - 版本兼容:如果使用Pydantic V1,只需将
model_dump替换为dict(),model_dump_json替换为json()即可,验证器写法保持一致。
内容的提问来源于stack exchange,提问作者Kenny Davidson
相关产品推荐
相关产品推荐

