-
Notifications
You must be signed in to change notification settings - Fork 132
JSON
While building web application, you might want to create a REST API with JSON
support. Then, you may need to convert all your Document into a JSON format
in order to pass it via the REST API. Unfortunately (or fortunately), MongoDB
support field format which is not supported by JSON. This is the case for datetime
but also for all your CustomTypes
you may have built and your embedded objects.
Document
supports the JSON import/export.
to_json
is a simply method which export you document into a JSON document:
>>> class MyDoc(Document):
... structure = {
... "bla":{
... "foo":unicode,
... "bar":int,
... },
... "spam":[],
... }
>>> con.register([MyDoc])
>>> mydoc = tutorial.MyDoc()
>>> mydoc['_id'] = u'mydoc'
>>> mydoc["bla"]["foo"] = u"bar"
>>> mydoc["bla"]["bar"] = 42
>>> mydoc['spam'] = range(10)
>>> mydoc.save()
>>> json = mydoc.to_json()
>>> json
u'{"_id": "mydoc", "bla": {"foo": "bar", "bar": 42}, "spam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}'
To load a JSON string into a Document
, use the from_json
class method:
>>> class MyDoc(Document):
... structure = {
... "bla":{
... "foo":unicode,
... "bar":int,
... },
... "spam":[],
... }
>>> json = '{"_id": "mydoc", "bla": {"foo": "bar", "bar": 42}, "spam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}'
>>> mydoc = tutorial.MyDoc.from_json(json)
>>> mydoc
{'_id': 'mydoc', 'bla': {'foo': 'bar', 'bar': 42}, 'spam': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
Note that from_json
will take care of all your embedded Document
if you used the to_json()
method to
generated the JSON. Indeed, some extra value has to be set: the database and the collection where
the embedded document lives. This is added by the to_json()
method:
>>> class EmbedDoc(Document):
... db_name = "test"
... collection_name = "mongokit"
... structure = {
... "foo":unicode
... }
>>> class MyDoc(Document):
... __database__ = "test"
... __collection__ = "mongokit"
... structure = {
... "doc":{
... "embed":EmbedDoc,
... },
... }
... use_autorefs = True
>>> con.register([EmbedDoc, MyDoc])
Let's create an embed doc:
>>> embed = tutorial.EmbedDoc()
>>> embed['_id'] = u"embed"
>>> embed['foo'] = u"bar"
>>> embed.save()
and embed this doc to another doc
>>> mydoc = tutorial.MyDoc()
>>> mydoc['_id'] = u'mydoc'
>>> mydoc['doc']['embed'] = embed
>>> mydoc.save()
Now let's see how look the generated json:
>>> json = mydoc.to_json()
>>> json
u'{"doc": {"embed": {"_collection": "tutorial", "_database": "test", "_id": "embed", "foo": "bar"}}, "_id": "mydoc"}'
As you can see, two new fields have been added : _collection
and _database
which represent respectively the collection and the database where the embed
doc has been saved. That information is needed to generate the embed
document. These are removed when calling the from_json()
method:
>>> mydoc = tutorial.MyDoc.from_json(json)
>>> mydoc
{u'doc': {u'embed': {u'_id': u'embed', u'foo': u'bar'}}, u'_id': u'mydoc'}
An the embed document is an instance of EmbedDoc:
>>> isinstance(mydoc['doc']['embed'], EmbedDoc)
True
from_json()
can detect if the _id
is an ObjectId
instance or a simple string. When you serialize an object with ObjectId
instance to json, the generated json object look like this:
'{"_id": {"$oid": "..."}, ...}'
Example:
>>> embed = tutorial.EmbedDoc()
>>> embed['foo'] = u"bar"
>>> embed.save()
>>> embed.to_json()
u'{"foo": "bar", "_id": {"$oid": "4b5ec47390bce737e5000002"}}'
the "$oid" field is added to tell from_json()
that '_id' is an ObjectId
instance.
The same append with embed doc:
>>> mydoc = tutorial.MyDoc()
>>> mydoc['doc']['embed'] = embed
>>> mydoc.save()
>>> mydoc.to_json()
{'doc': {'embed': {u'_id': ObjectId('4b5ec45090bce737cb000002'), u'foo': u'bar'}}, '_id': ObjectId('4b5ec45090bce737cb000003')}