📜 ⬆️ ⬇️

Using MongoDB in Django

- document-oriented database management system (DBMS) with open source code that does not require the description of the table schema. Written in C ++ and distributed under a Creative Commons license.

Recently becoming quite popular and demanded. And here was the idea to use it in conjunction with the framework Django. Actually what will be discussed further.


')
To solve the problem we will use the application mongodb-engine. This application is closely related to several other applications, the installation of which we will do in the beginning.

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, will not be superfluous.
 pip install hg+https://bitbucket.org/wkornewald/djangotoolbox 


And now we install 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 the 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, representing 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'] 


Option indicating the type:
 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 for organizing connections 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, ...} 


Option indicating the type:
 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 statement to update
 .update(..., {'$set': {'title': 'Everything is the same'}}) 


And also 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 do not have enough Django ORM capabilities, you can use MongoDB queries without the standard mechanism.

raw_query () - takes one argument, returns data as a standard Django queryset. Which 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() 


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 there are not enough standard tools for us to update the 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 performed for each foo in the database.

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

References:
MongoDB
mongodb-engine
An example of creating a blog
Github

Source: https://habr.com/ru/post/160191/


All Articles