Chris Umbel

Using MongoDB as a Backend for Django with django-mongodb-engine

MongoDB logoI've been pretty taken with MongoDB of late. It's nearly disgusting how productive it is. However, like all database systems it's only as productive as the higher-level systems that interface with it.

Personally I've used it primarily from Java and Ruby on Rails (via MongoMapper) and from Python via PyMongo.

PyMongo essentially exposes MongoDB via Python dictionaries. Sure, it's plenty elegant and plenty pythonic but when it came to django I wanted was something more MongoMapper-like, an honest-to-goodness Object-Document-Mapper.

django logoMonths and months ago when I looked into the existence of a MongoDB driver for django all that turned up was dead, false-start projects, but after revisiting it recently django-mongodb-engine came to my attention. django-mongodb-engine is pretty much exactly what I was looking for. The authors describe it as, "a database backend that adds mongodb support to django". In this post I intend to introduce it to you.

I'm going to assume you're comfortable getting a django application started. If that's not the case please check out the official getting-started docs.

Requirements

In order to leverage MongoBD from django you'll need the following software installed and operating:

  • Python - If you're reading this article odds are you already have it.
  • MongoDB - I guess this is somewhat self explanatory, but you'll need MongoDB itself.
  • django-norel - is a special version of django designed for use with non-relational database engines in general.
  • django tooblox - a general purpose utility library upon which django-mongodb-engine depends
  • mongodb-engine - the MongoDB driver for django.

Application

Infrastructure in place I'll go ahead and create a django project named "testproj" with an application named "testapp".

django-admin.py startproject testproj
cd testproj/
django-admin.py startapp testapp

Setup

Naturally the django project must be configured to talk to a specific database in settings.py.

DATABASES = {
    'default': {
        'ENGINE': 'django_mongodb_engine',
        'NAME': 'mydatabase',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '27017',
        'SUPPORTS_TRANSACTIONS': False,
    },
}

Edit 2012-11-20: Older versions may require ENGINE to be 'django_mongodb_engine.mongodb'.

Models

In said application you could create a model in models.py like

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length = 64)
    content = models.TextField()

It looks like a standard old django model, right? Nothing fancy here, just a plain old model with plain old fields.

Note that it's important to not create and AutoField named "id" or things will blow up when saving. That's because Mongo wants to put a proper ObjectId in there.

Saving

We can then save some model data strait away from a django view.

from django.http import HttpResponse
from models import *

def testview(request):
  article = Article(title = 'test title',
    content = 'test content')
  article.save()

  return HttpResponse("

Saved!

")

If you then peer into Mongo with a native javascript query query like

db.testapp_article.find()

you'll find your document returned

{ "_id" : ObjectId("4cb4f9a01a8ff904fa000001"), "content" : "test content", "title" : "test title" }

Querying

of course it's a simple matter to query Mongo from django to retrieve a list of Article objects just like you would with a relational store.

articles = Article.objects.all()

Embedding Documents

Many document-database-esque features are covered as well, but I'll just touch on one here. With a minor alteration to our model

from django.db import models
from django_mongodb_engine.mongodb.fields import EmbeddedModel
from django_mongodb_engine.fields import ListField

class Comment(EmbeddedModel):
  name = models.CharField(max_length = 160)
  content = models.TextField()

class Article(models.Model):
  title = models.CharField(max_length = 160)
  content = models.TextField()
  comments = ListField()  

then we can embed Comment documents into Articles.

article = Article(title = 'test title', 
  content = 'test content')

article.comments.append(Comment(name = 'alice', description = 'foo bar'))
article.comments.append(Comment(name = 'bob', description = 'fun baz'))

article.save()

Conclusion

Thanks to the hard work of others it's a simple matter for us to use MongoDB as a backend for django. To see some specific examples of non-relational-style features check out the tests from the django-mongodb-engine project.

Wed Oct 13 2010 01:14:48 GMT+0000 (UTC)

4 Comments Comment Feed - Permalink
i'm clearly understood from this above examples, thank u!!!
by Thanga Vignesh Raja on Mon Apr 16 2012 07:19:15 GMT+0000 (UTC)
<h1>nice job</h1>
by hdks on Fri Dec 14 2012 18:12:33 GMT+0000 (UTC)
django tooblox -> django toolbox
by Jakob Olsen on Fri Apr 12 2013 07:45:24 GMT+0000 (UTC)
djfhlkvlkvlfkvh
by ascjlakdjf on Thu Nov 13 2014 02:42:47 GMT+0000 (UTC)
Add a comment
Name
E mail (Private)
URL
Follow Chris
RSS Feed
Twitter
Facebook
CodePlex
github
LinkedIn
Google