全局配置 Pydantic 处理 UUID 序列化方案

全局配置 Pydantic 处理 UUID 序列化方案

如果你想在 FastAPI 应用中全局处理 UUID 序列化问题,而不需要为每个模型单独配置,有以下几种全局解决方案:

方案1:自定义 FastAPI JSON 编码器(推荐)

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from uuid import UUID
import json

app = FastAPI()

# 自定义 JSON 编码器
def custom_json_encoder(obj):
    if isinstance(obj, UUID):
        return str(obj)
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

# 覆盖默认的 jsonable_encoder 行为
jsonable_encoder.ENCODERS_BY_TYPE[UUID] = lambda x: str(x)

# 或者更彻底的覆盖(如果需要处理更多类型)
app.json_encoder = json.JSONEncoder(default=custom_json_encoder)

方案2:修改 Pydantic 基础配置(影响所有模型)

from pydantic import BaseConfig

# 全局修改 Pydantic 的 JSON 编码器
BaseConfig.json_encoders = {
    UUID: lambda v: str(v),
}

# 注意:这会影响应用中所有 Pydantic 模型

方案3:创建自定义基础模型

from pydantic import BaseModel
from uuid import UUID

class CustomBaseModel(BaseModel):
    class Config:
        json_encoders = {
            UUID: lambda v: str(v),
        }

# 然后让所有模型继承这个基础模型
SomeModelPydantic = pydantic_model_creator(
    SomeModel,
    name="SomeModelPydantic",
    base=CustomBaseModel  # 使用自定义基础模型
)

方案4:猴子补丁 Tortoise 的 pydantic_model_creator

from tortoise.contrib.pydantic import pydantic_model_creator
from pydantic import BaseConfig

original_creator = pydantic_model_creator

def patched_pydantic_model_creator(*args, **kwargs):
    model = original_creator(*args, **kwargs)
    if not hasattr(model.Config, 'json_encoders'):
        model.Config.json_encoders = {}
    model.Config.json_encoders[UUID] = lambda v: str(v)
    return model

# 应用猴子补丁
pydantic_model_creator = patched_pydantic_model_creator

推荐方案

推荐使用方案1,因为它:

  1. 是 FastAPI 官方推荐的方式
  2. 不会影响 Pydantic 的其他行为
  3. 作用范围明确,只影响 FastAPI 的 JSON 响应
  4. 可以轻松扩展以处理其他自定义类型的序列化

注意事项

  • 这些全局修改应该在应用启动时尽早执行
  • 如果使用了异步 ORM(如 Tortoise-ORM),确保在 ORM 初始化之前完成这些配置
  • 全局修改可能会影响应用中其他部分的预期行为,建议在测试环境中充分验证
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容