JSON support
============

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`:

`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]}'

:`from_json`:

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`\ s 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):
...    db_name = "test"
...    collection_name = "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

ObjectId support
----------------

`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": "..."}, ...}'

>>> 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')}

