Using MongoDB in Django

    - An open source document-oriented database management system (DBMS) that does not require a description of the table layout. It is written in C ++ and distributed under the Creative Commons license.

    Recently it has become quite popular and in demand. And so the idea came up of using it in conjunction with the Django framework. Actually what will be discussed further.



    To solve this problem, we will use the mongodb-engine application. This application is closely connected with several other applications, the installation of which we will do first.

    Django-nonrel - used to support NoSQL in Django.
    pip install hg+https://bitbucket.org/wkornewald/django-nonrel
    


    djangotoolbox - a set of tools for working with non-relational databases, it will not be superfluous.
    pip install hg+https://bitbucket.org/wkornewald/djangotoolbox
    


    And now we put the mongodb-engine:
    pip install git+https://github.com/django-nonrel/mongodb-engine
    


    Specify our database in settings:
    DATABASES = {
       'default' : {
          'ENGINE' : 'django_mongodb_engine',
          'NAME' : 'my_database'
       }
    }
    


    If necessary, you can also specify host, port, user, password.

    This application provides two types of fields for storing arbitrary data that are not included in the standard django model.

    Listfield

    Lists and the like, representation of arrays in BSON format

    from djangotoolbox.fields import ListField
    class Post(models.Model):
        ...
        tags = ListField()
    


    >>> Post(tags=['django', 'mongodb'], ...).save()
    >>> Post.objecs.get(...).tags
    ['django', 'mongodb']
    


    Type option:
    class Post(models.Model):
        ...
        edited_on = ListField(models.DateTimeField())
    


    >>> post = Post(edited_on=['1010-10-10 10:10:10'])
    >>> post.save()
    >>> Post.objects.get(...).edited_on
    [datetime.datetime([1010, 10, 10, 10, 10, 10])]
    


    This type of field is convenient to use for one-to-many communication:
    from djangotoolbox.fields import EmbeddedModelField, ListField
    class Post(models.Model):
        ...
        comments = ListField(EmbeddedModelField('Comment'))
    class Comment(models.Model):
        ...
        text = models.TextField()
    


    EmbeddedModelField - used to organize relationships between models.

    Dictfield

    The second type of field is DictField, which is used in BSON for objects.

    from djangotoolbox.fields import DictField
    class Image(models.Model):
        ...
        exif = DictField()
    


    >>> Image(exif=get_exif_data(...), ...).save()
    >>> Image.objects.get(...).exif
    {u'camera_model' : 'Spamcams 4242', 'exposure_time' : 0.3, ...}
    


    Type option:
    class Poll(models.Model):
        ...
        votes = DictField(models.IntegerField())
    

    >>> Poll(votes={'bob' : 3.14, 'alice' : '42'}, ...).save()
    >>> Poll.objects.get(...).votes
    {u'bob' : 3, u'alice' : 42}
    


    Data update


    Post.objects.filter(...).update(title='Everything is the same')
    


    You can use the $ set operator to update
    .update(..., {'$set': {'title': 'Everything is the same'}})
    


    As well as the function F ()
    Post.objects.filter(...).update(visits=F('visits')+1)
    


    The result is something like this:
    .update(..., {'$inc': {'visits': 1}})
    


    Using low-level queries

    If you lack the capabilities of Django ORM, you can use queries to MongoDB bypassing the standard mechanism.

    raw_query () - takes one argument, returns data in the form of a standard Django queryset. What is good for further data processing.

    Example with geo data, model:
    from djangotoolbox.fields import EmbeddedModelField
    from django_mongodb_engine.contrib import MongoDBManager
    class Point(models.Model):
        latitude = models.FloatField()
        longtitude = models.FloatField()
    class Place(models.Model):
        ...
        location = EmbeddedModelField(Point)
        objects = MongoDBManager()
    


    we get all the points near the specific coordinates:
    >>> here = {'latitude' : 42, 'longtitude' : 3.14}
    >>> Place.objects.raw_query({'location' : {'$near' : here}})
    


    raw_update () - used if we don’t have enough standard tools for updating data.

    Model:
    from django_mongodb_engine.contrib import MongoDBManager
    class FancyNumbers(models.Model):
        foo = models.IntegerField()
        objects = MongoDBManager()
    


    using:
    FancyNumbers.objects.raw_update({}, {'$bit' : {'foo' : {'or' : 42}}})
    

    In this example, a bitwise or is executed for each foo in the database.

    The possibilities of this bundle do not end there, but if you list everything, then the article is not justifiably delayed. The full description and examples can be viewed at the links below.

    Links:
    MongoDB
    mongodb-engine GitHub
    Blog Creation Example

    Also popular now: