Pydantic V2升级:如何为自定义类配置全局可自动发现的JSON序列化逻辑?
解决方案:将序列化逻辑内置到RockBase类中
要让Pydantic自动识别并应用RockBase的序列化逻辑(包括嵌套在Any类型结构中的场景),你可以通过修改RockBase的__get_pydantic_core_schema__方法,将序列化逻辑直接整合到类的核心Schema定义中,无需依赖Annotated+PlainSerializer的方式。
修改后的RockBase实现
from typing import Any, Dict from pydantic import BaseModel, ConfigDict from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import CoreSchema, core_schema class RockBase: def __init__(self, value): self.value = value @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema: # 定义验证逻辑 def validate(v): # 保留原有验证逻辑,可根据需求调整 return v if isinstance(v, cls) else cls(v) # 定义序列化逻辑 def serialize(v): return "a_string" # 替换为你的实际序列化逻辑 # 返回整合了验证与序列化的CoreSchema return core_schema.no_info_plain_serializer_function( serialize, return_type=str, schema=core_schema.general_plain_validator_function(validate), when_used="always" ) @classmethod def __get_pydantic_json_schema__(cls, _core_schema: CoreSchema, handler: GetJsonSchemaHandler) -> Dict[str, Any]: return {"type": "string"} # 保持原有JSON Schema定义 class SimpleAsteroid(BaseModel): contains: Any # 支持Any或其他复杂嵌套类型 model_config = ConfigDict(arbitrary_types_allowed=True) # 测试嵌套场景 mm2 = SimpleAsteroid(contains={"extra":{"nested":{"value": RockBase("it's deep")}}}) print(mm2.model_dump_json()) # 输出: {"contains":{"extra":{"nested":{"value":"a_string"}}}}
关键说明
- 核心逻辑整合:通过
core_schema.no_info_plain_serializer_function将序列化函数与验证逻辑绑定,生成包含完整序列化规则的CoreSchema,这样Pydantic在处理任何RockBase实例时(无论是否嵌套)都会自动应用该序列化逻辑。 - 移除Annotated依赖:无需再使用
Annotated包装类型,直接使用RockBase作为类型注解即可,甚至字段类型为Any时,Pydantic也能识别嵌套的RockBase实例并触发序列化。 - 兼容原有验证逻辑:保留了原有的验证逻辑,确保类型验证与序列化逻辑统一维护在类内部。
内容的提问来源于stack exchange,提问作者Polyphil
相关产品推荐
相关产品推荐

