Bootstrapping a Django-with-Mongo project. A Layman’s guide.

Posted: July 6th, 2010 | Author: | Filed under: The IT Life | Tags: , , ,

Django and Mongo are a great combination for rapid prototyping. I’ve been using these two technologies for a while and thought I would share my notes on how to bootstrap a new project. I wasn’t able to find a single walk-through that covered the various bumps-in-the-road that I was running over; hence this post. The process that follows was written for Ubuntu 10.04 (amd64) but should translate to other flavors.

Most of this is jazz compiled from various sources. Specifically:

First, the basics. We’ll need to get the python environment set up.

$ sudo apt-get install python-setuptools
$ sudo apt-get install python-virtualenv
$ sudo easy_install pip
$ sudo pip install virtualenvwrapper

I like to keep some organization by language, so …

$ mkdir -p ~/src/python/virtuals
$ cd ~/src/python/virtuals

Now, let’s create a virtual environment.

$ virtualenv --no-site-packages --python=/usr/bin/python2.6 virt01
$ cd virt01
$ source bin/activate

That’s actually all you need for any virtual environment.

Before we move on, install mongo and the python headers if they’re not already installed …

$ sudo apt-get install mongodb
$ sudo apt-get install python-dev

The python-dev package was installed due to a “missing Python.h” file during my first pymongo install. YMMV.

Now, thanks to an example by SaltyCrane, we can quickly install all the necessary dependencies with one go.  Create a file called reqs.txt and paste in the following:

pymongo
-e git+http://github.com/FlaPer87/django-mongodb-engine.git#egg=django_mongodb_engine
-e hg+http://bitbucket.org/wkornewald/django-nonrel#egg=Django
-e hg+http://bitbucket.org/wkornewald/djangotoolbox#egg=djangotoolbox

Now, use pip to pull in all of the dependencies.

$ pip install -r reqs.txt

Hopefully all went well. Feel free to update me if something didn’t work as described/etc.

Now, let’s make a django project for our pinky-chick.com startup.

$ mkdir -p ~/src/python/virtuals/virt01/src/pinky-chick.com
$ cd ~/src/python/virtuals/virt01/src/pinky-chick.com
$ django-admin.py startproject pcsite
$ cd pcsite

Open up the settings.py file and do as ABP suggest:

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

INSTALLED_APPS = (
    'djangotoolbox',
    ...
)

And validate it …

$ python manage.py validate

Now, let’s do something pinky …

Pinky Chick

We will sell a single make of high-quality wine. Our product is cool and refreshing just like the chicks who love it. We’ll make 5 million dollars in the first year as investors pound down our door to throw money into our Web2.0 hole.

Let’s create our shop …

$ cd ~/src/python/virtuals/virt01/src/pinky-chick.com/pcsite
$ python manage.py startapp shop

… and add some models. Open up shop/models.py and paste in the following.

from django.db import models
"""
Our yummy stuff
"""
class Product( models.Model ):
    name = models.CharField( max_length=200 )
    vintage = models.CharField( max_length=200 )
    production = models.IntegerField( 'Amount produced in volumn' )
    bottles = models.IntegerField( 'Number of bottles produced' )

"""
Real cool dude(ttes)
"""
class Customer( models.Model ):
    first_name = models.CharField( max_length=200 )
    last_name = models.CharField( max_length=200 )

"""
How our investors afford nice cars ...
"""
class Purchase( models.Model ):
    date_ordered = models.DateTimeField( 'Date purchased' )
    date_processed = models.DateTimeField( 'Date processed' )
    date_delivered = models.DateTimeField( 'Date delivered' )
    product = models.ForeignKey( Product )
    customer = models.ForeignKey( Customer )

Now, before we do the standard syncing, we’ll need to take care of a current bug.

$ vi manage.py

It should look something like this (adding import os …):

#!/usr/bin/env python
from django.core.management import execute_manager

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
import django_mongodb_engine.mongodb.fields

try:

Ok. Let’s tell django about our shop. Open up settings.py and add our app …

INSTALLED_APPS = (
    ...
    'pcsite.shop',
)

We can now sync up.

$ python manage.py syncdb

That’s it, our shop is now running on django and mongo in a virtual environment.

Here’s some fun …

$ python manage.py shell
>>> from pcsite.shop.models import Customer, Product, Purchase
>>> Customer.objects.all()
[]

>>> c = Customer( first_name='Dennis', last_name='Gurnick' )
>>> c.save()
>>> c
<Customer: Customer object>

>>> import datetime
>>> p = Product( name='SuperSexyVino', vintage='2010', production=100, bottles=10 )
>>> p.save()
>>> p
<Product: Product object>

>>> b = Purchase( product=p, customer=c, date_ordered=datetime.datetime.now(), date_processed=datetime.datetime.now(), date_delivered=datetime.datetime.now() )
>>> b.save()
>>> b
<Purchase: Purchase object>

And on the mongo side, just to prove we’re grooving …

(virt01)dennis@race:~$ mongo
MongoDB shell version: 1.2.2
url: test
connecting to: test
type "exit" to exit
type "help" for help
> use pinkychick
switched to db pinkychick

> db.shop_customer.find()
{ "_id" : ObjectId("4c33479c2e2a7a1afa000000"), "first_name" : "Dennis", "last_name" : "Gurnick" }

> db.shop_product.find()
{ "_id" : ObjectId("4c3347cb2e2a7a1afa000001"), "vintage" : "2010", "production" : 100, "bottles" : 10, "name" : "SuperSexyVino" }

> db.shop_purchase.find()
{ "_id" : ObjectId("4c33481e2e2a7a1afa000002"), "product_id" : ObjectId("4c3347cb2e2a7a1afa000001"), "date_ordered" : "Tue Jul 06 2010 12:13:32 GMT+0200 (CET)", "date_processed" : "Tue Jul 06 2010 12:13:32 GMT+0200 (CET)", "date_delivered" : "Tue Jul 06 2010 12:13:32 GMT+0200 (CET)", "customer_id" : ObjectId("4c33479c2e2a7a1afa000000") }

Fin.


facebook comments:


Leave a Reply