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.


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.


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


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

    'default': {
        'ENGINE': 'django_mongodb_engine',
        'NAME': 'mydatabase',
        'USER': '',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '27017',

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


In said application you could create a model in 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.


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

  return HttpResponse("



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


you'll find your document returned

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


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


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)

Follow Chris
RSS Feed