Pantry Application – beginning my first Django Project

Posted on February 2nd, 2011

A few weeks ago, I wrote about designing the basic database/model structure of an application to keep track of my pantry inventory. The next step is to apply the model to a web framework. I would like to outline creating a basic application for the design in a few different frameworks and describe their ease of setup and use. To begin with, I decided to try it out in Django (http://www.djangoproject.com/), a web framework written in Python. Ultimately, this is probably the one that I will stick with since I want to advance myself as a Python developer and learning Django (especially coming from a web development background) is a natural first step.

Quick notes about Django: After working on this initial project, I was impressed how easy it was to start the project through model development, and look forward to seeing how easy it is in comparison to other popular frameworks; (all that I try are going to be in languages I’m not fluent in, to be fair). But not everything was totally intuitive, and there were a few times where I was lucky to be pair programming with Jesse, as he knows Django and could point out things I was missing in my models. Not that I couldn’t have done it without a pair — the documentation is AMAZING and there’s a fantastic tutorial online. These are great things.

First of all, I decided to set up a development environment on my netbook using the following steps. (The tutorial gives different instructions for installing Django, but Jesse insisted I install pip. And I chose not to bother with virtualenv, for now.)

1) Installed pip:
$ sudo easy_install pip

2) Used pip to install it globally
$ sudo pip install django

3) Created a new project
$ django-admin.py startproject pantry

4) Ran the server
$ python manage.py runserver

and here we go!

Awesome! Django is running! Now time to create the pantry inventory application and build my model.

settings.py
The next step was to edit settings.py. For my development version of the application, at least to start, I decided sqlite would be fine, which made the settings for it pretty easy:

  DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'    .
          'NAME': 'data',                      # Or path to database file if using sqlite3.
          'USER': '',                      # Not used with sqlite3.
          'PASSWORD': '',                  # Not used with sqlite3.
          'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
          'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
      }
  }

I scrolled down and uncommented ‘django.contrib.admin’ in INSTALLED_APPS, since I planned on using the built-in Django administration tool for my application.

Creating the application

From my pantry directory, I typed the following to create my app:
$ python manage.py startapp inventory

models.py
Now that my project and application were created, I was ready to apply the pantry model that I had designed earlier to my new application.

Again, the example of models.py in the Django tutorial was a great place to start. From there, I used the field type documentation in order to determine the syntax to use for the different types of fields and relationships.

Using that, I came up with the following (only showing Food here, but all classes can be viewed in the final models.py on Github):

 class Food(models.Model):
     name = models.CharField(max_length=100)
     current_amount = models.FloatField()
     vegetarian = models.BooleanField(default=True)
     staple = models.BooleanField(default=False)
     measurement_unit = models.ForeignKey('MeasurementUnit')
     categories = models.ManyToManyField('Category')

Besides defining the fields/relationships, I also added a few more things to my classes. For the admin, I needed to define something useful to display, and so added the following:

     def __str__(self):
         return self.name

Lastly, I wanted to define what field should be used for ordering. Django offers some “Meta” options for its models [documentation].

The option I used is “ordering”, which is given as a tuple or list of strings. After adding that, my complete Food class is:

  class Food(models.Model):
      name = models.CharField(max_length=100)
      current_amount = models.FloatField()
      vegetarian = models.BooleanField(default=True)
      staple = models.BooleanField(default=False)
      measurement_unit = models.ForeignKey('MeasurementUnit')
      categories = models.ManyToManyField('Category')

     class Meta(object):
         ordering = ('name',)

      def __str__(self):
          return self.name

Pretty simple! Next, I added in classes for Category, Purchase, MeasurementUnit, Store and Brand.

Create tables and instruct Django to use inventory app

After finishing models.py, I needed to open up settings.py to tell it to include my inventory app:

  INSTALLED_APPS = (
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.sites',
      'django.contrib.messages',
      # Uncomment the next line to enable the admin:
      'django.contrib.admin',
      # Uncomment the next line to enable admin documentation:
      # 'django.contrib.admindocs',
      'pantry.inventory',
 )

Almost complete!

Finally, I had to tell it to build my inventory tables, and so I ran syncdb. Since this was the first time running syncdb since making my initial changes to settings.py, it also created my admin tables at this time:

$ python manage.py syncdb

Checking out the new application in Django admin

Now, with the Django server running, and new app created, I could view my models in the admin interface here (local to my computer of course): http://127.0.0.1:8000/admin/inventory/

And by clicking on “add” next to foods, I could see my model in use (screenshot was done after populating a few of the related table fields):

And, that’s it!

Next up
In a future post, I will cover building interfaces for my new application along with working unit conversion into the functionality. Any suggestions for resources for the unit conversion are welcome!

The entire Django project discussed in this post is available on Github: https://github.com/jenstander/pantry

Jen

Click here to view and leave comments!