Skip to content

serialization

Field serializers

可以通过PlainSerializerWrapSerializer 对字段层面进行自定义序列化

WrapSerializer 支持在自定义函数中使用 pydantic 内置的序列化行为

PlainSerializer

Example
from typing import Annotated, Any

from pydantic import BaseModel, PlainSerializer, ConfigDict


def ser_number(value: Any) -> Any:
    if isinstance(value, MyValue):
        value = value.value

    if isinstance(value, int):
        return value * 2
    else:
        return value


class MyValue:
    def __init__(self, value):
        self.value = value


class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    val: Annotated[MyValue, PlainSerializer(ser_number)]


print(Model(val=MyValue(10)).model_dump_json())
# > {"val":20}

print(Model(val=MyValue("v")).model_dump_json())
# > {"val":"v"}

WrapSerializer

使用 Annotated 在注解时添加自定义序列化行为.

可以选择把序列化行为委托给 SerializerFunctionWrapHandler 参数获得序列化后的值

Example
from typing import Annotated, Any

from pydantic import BaseModel, SerializerFunctionWrapHandler, WrapSerializer, ConfigDict


def ser_number(value: Any, handler: SerializerFunctionWrapHandler) -> Any:
    if isinstance(value, MyValue):
        value = value.value

    if isinstance(value, int):
        return value * 2
    else:
        return value


class MyValue:
    def __init__(self, value):
        self.value = value


class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    val: Annotated[MyValue, WrapSerializer(ser_number)]


print(Model(val=MyValue(10)).model_dump_json())
# > {"val":20}

print(Model(val=MyValue("v")).model_dump_json())
# > {"val":"v"}

Model serializers

使用 model_serializer 装饰器注册一个实现模型层面的序列化函数

PlainSerializer

Example
from pydantic import BaseModel, model_serializer, ConfigDict


class MyValue:
    def __init__(self, value):
        self.value = value


class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    val: MyValue

    @model_serializer(mode="plain")
    def serializer(self) -> dict:
        val = self.val.value * 2 if isinstance(self.val.value, int) else self.val.value
        return {"value": val}


print(Model(val=MyValue(10)).model_dump_json())
# > {"val":20}

print(Model(val=MyValue("v")).model_dump_json())
# > {"val":"v"}

WarpSerializer

Example
from pydantic import BaseModel, model_serializer, ConfigDict, SerializerFunctionWrapHandler
from datetime import datetime


class MyValue:
    def __init__(self, value):
        self.value = value


class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)
    val: MyValue

    @model_serializer(mode="wrap")
    def serializer(self, handler: SerializerFunctionWrapHandler) -> dict:
        if isinstance(self.val.value, datetime):
            return {"value": handler(self.val.value)}
        val = self.val.value * 2 if isinstance(self.val.value, int) else self.val.value
        return {"value": val}


print(Model(val=MyValue(10)).model_dump_json())
# > {"val":20}

print(Model(val=MyValue("v")).model_dump_json())
# > {"val":"v"}

print(Model(val=MyValue(datetime.fromisoformat("2025-01-01T12:00:00+0800"))).model_dump_json())
# > {"value":"2025-01-01T12:00:00+08:00"}