如何在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
相关产品推荐
相关产品推荐

