PyMongo/MongoEngine如何将MongoDB查询结果的ObjectId转为字符串格式?
解决方案
PyMongo 处理方案
方式1:使用内置序列化工具配置
PyMongo 的 bson.json_util 模块可直接处理 ObjectId 序列化,配置参数即可转为字符串格式:
from bson.json_util import dumps, JSONOptions from flask import jsonify import json # 配置JSON选项,指定ObjectId序列化为字符串 json_options = JSONOptions(json_mode='STRICT') # 查询数据库文档 docs = db.target_collection.find() # 序列化并转换为前端可识别的JSON serialized_data = dumps(docs, json_options=json_options) # 若用Flask框架,直接返回处理后的响应 return jsonify(json.loads(serialized_data))
方式2:全局配置Web框架的JSON编码器
以Flask为例,自定义全局JSON编码器,自动将所有ObjectId转为字符串,无需重复处理:
from bson import ObjectId from flask import Flask, jsonify import json app = Flask(__name__) class MongoJSONEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, ObjectId): return str(obj) return super().default(obj) # 绑定编码器到Flask应用 app.json_encoder = MongoJSONEncoder # 接口示例 @app.route('/api/data') def fetch_data(): docs = list(db.target_collection.find()) return jsonify(docs)
MongoEngine 处理方案
方式1:自定义全局序列化函数
from mongoengine import Document from bson import ObjectId from flask import jsonify def serialize_mongo_doc(doc): if isinstance(doc, Document): doc_dict = doc.to_mongo().to_dict() doc_dict['_id'] = str(doc_dict['_id']) return doc_dict elif isinstance(doc, ObjectId): return str(doc) raise TypeError(f"无法序列化类型: {type(doc)}") # 接口中调用 docs = YourDocumentClass.objects.all() serialized_docs = [serialize_mongo_doc(doc) for doc in docs] return jsonify(serialized_docs)
方式2:给Document类添加序列化方法
直接在模型类中定义序列化方法,调用更直观:
from mongoengine import Document, StringField class YourDocumentClass(Document): content = StringField() def to_frontend_json(self): doc_dict = self.to_mongo().to_dict() doc_dict['_id'] = str(doc_dict['_id']) return doc_dict # 调用示例 docs = YourDocumentClass.objects.all() serialized_docs = [doc.to_frontend_json() for doc in docs] return jsonify(serialized_docs)
FastAPI 适配方案
若使用FastAPI,可配合jsonable_encoder实现自动转换:
from fastapi import FastAPI from bson import ObjectId from fastapi.encoders import jsonable_encoder app = FastAPI() def encode_mongo_data(data): if isinstance(data, list): return [encode_mongo_data(item) for item in data] if isinstance(data, dict): for k, v in data.items(): if isinstance(v, ObjectId): data[k] = str(v) elif isinstance(v, (dict, list)): data[k] = encode_mongo_data(v) return data return data @app.get("/api/data") async def get_data(): docs = list(db.target_collection.find()) return jsonable_encoder(encode_mongo_data(docs))
以上方法均无需手动遍历每个文档修改_id,通过全局配置或工具类即可统一处理,直接输出符合前端预期的{"_id":"63693f438cdbc3adb5286508", ...}格式。
内容的提问来源于stack exchange,提问作者Rodrigo Alarcón
相关产品推荐
相关产品推荐

