You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic 2.x.x与FastAPI 1.x.x中替换pydantic.json.ENCODERS_BY_TYPE[ObjectId] = str

Pydantic v2 序列化 ObjectId 的替代方案

在Pydantic迁移到新核心(v2版本)后,原有的pydantic.json.ENCODERS_BY_TYPE[ObjectId] = str写法确实被移除了,以下是几种适配FastAPI的原生实现方式:

方法一:字段级指定序列化器

适合仅需处理单个字段的场景,直接在字段上定义序列化规则:

from bson import ObjectId
from pydantic import BaseModel, PlainSerializer

class Item(BaseModel):
    id: ObjectId = PlainSerializer(lambda x: str(x), return_type=str)
    # 若需规范OpenAPI文档,可追加JSON Schema定义
    # id: ObjectId = PlainSerializer(lambda x: str(x), return_type=str, with_json_schema={"type": "string"})

方法二:全局基类统一配置

通过自定义基类注册全局序列化规则,所有继承该基类的模型都会自动生效:

from bson import ObjectId
from pydantic import BaseModel, ConfigDict

class BaseMongoModel(BaseModel):
    model_config = ConfigDict(json_encoders={ObjectId: str})

# 业务模型继承基类即可
class Item(BaseMongoModel):
    id: ObjectId
    name: str

方法三:FastAPI响应层面自定义编码

如果需要在接口响应环节统一处理,可重写jsonable_encoder:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder as fastapi_encoder
from bson import ObjectId
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    id: ObjectId
    name: str

def custom_jsonable_encoder(obj):
    if isinstance(obj, ObjectId):
        return str(obj)
    return fastapi_encoder(obj)

@app.get("/item/{item_id}", response_model=Item)
async def get_item(item_id: ObjectId):
    item = {"id": item_id, "name": "Test Item"}
    return JSONResponse(content=custom_jsonable_encoder(item))

注意:以上方案均适配Pydantic v2及最新版FastAPI,确保依赖版本兼容即可正常使用。

内容的提问来源于stack exchange,提问作者furtim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:20:58