for p in db.collection.find({"test_set":"abc"}):
posts.append(p)
thejson = json.dumps({'results':posts})
return HttpResponse(thejson, mimetype="application/javascript")
Dans mon code Django/Python, je ne peux pas retourner un JSON à partir d'une requête mongo à cause de "ObjectID". L'erreur indique que "ObjectID" n'est pas sérialisable.
Que dois-je faire? Un moyen hacky serait de parcourir:
for p in posts:
p['_id'] = ""
Le module json ne fonctionnera pas en raison de choses comme l'ObjectID.
Heureusement PyMongo fournit json_util qui ...
... autorise [s] l'encodage et le décodage spécialisés des documents BSON en mode Strict de Mongo Extended JSON. Cela vous permet d'encoder/décoder des documents BSON en JSON même lorsqu'ils utilisent des types BSON spéciaux.
Voici un exemple simple, utilisant pymongo 2.2.1
import os
import sys
import json
import pymongo
from bson import BSON
from bson import json_util
if __name__ == '__main__':
try:
connection = pymongo.Connection('mongodb://localhost:27017')
database = connection['mongotest']
except:
print('Error: Unable to Connect')
connection = None
if connection is not None:
database["test"].insert({'name': 'foo'})
doc = database["test"].find_one({'name': 'foo'})
return json.dumps(doc, sort_keys=True, indent=4, default=json_util.default)
Il est assez facile d'écrire un sérialiseur personnalisé qui gère les ObjectIds. Django en inclut déjà un qui gère les décimales et les dates, vous pouvez donc étendre cela:
from Django.core.serializers.json import DjangoJSONEncoder
from bson import objectid
class MongoAwareEncoder(DjangoJSONEncoder):
"""JSON encoder class that adds support for Mongo objectids."""
def default(self, o):
if isinstance(o, objectid.ObjectId):
return str(o)
else:
return super(MongoAwareEncoder, self).default(o)
Maintenant, vous pouvez simplement dire à json
d'utiliser votre sérialiseur personnalisé:
thejson = json.dumps({'results':posts}, cls=MongoAwareEncoder)
Quelque chose de plus simple qui fonctionne pour moi sur Python 3.6 en utilisant le moteur == 1.1 pymongo == 3.4.0
from bson.json_util import dumps, loads
for mongo_doc in await cursor.to_list(length=10):
# mongo_doc is a <class 'dict'> returned from the async mongo driver, in this acse motor / pymongo.
# result of executing a simple find() query.
json_string = dumps(mongo_doc)
# serialize the <class 'dict'> into a <class 'str'>
back_to_dict = loads(json_string)
# to unserialize, thus return the string back to a <class 'dict'> with the original 'ObjectID' type.