Django and the Django Software Foundation

Fret Free

© Alexey Klementiev, Fotolia

© Alexey Klementiev, Fotolia


We talk to one of the creators of the Django project about the formation of the Django Software Foundation, and we show you how to get started with this user-friendly web framework.

In the summer of 2005, yet another web framework was released into the open source world [1]. Only three short years since Django's release, it has gained enough traction to inspire the formation of the Django Software Foundation [2]. With the formation of the DSF, Django joins an impressive list of other projects with their own foundations, including Apache, Perl, and Python.

What Is Django?

Django is a Python web development "framework," or set of libraries, that allows developers to work on the unique/interesting parts of an application without worrying much about the boring infrastructure under the hood. Django uses the MVC pattern like many other frameworks, such as Ruby on Rails and the various Perl and PHP frameworks.

One of Django's killer features is its incredibly slick admin interface that is automatically built for you. In this article, I will walk through the steps required to build a small Twitter-like application so you can see the admin in action.

Django has been used to build a lot of high-profile websites [3], such as,, and Also, it is the default framework included with Google's AppEngine, and I've heard that Google uses it to some extent internally. Django is also the foundation of the commercial CMS Ellington, which is used by several large news organizations, including The Washington Post.

Jacob Kaplan-Moss, President of the Django Software Foundation and one of the creators of Django, said that the Foundation was created so the project could take the next step in its life cycle as an open source project. "We've obviously succeeded in attracting a large, vibrant community, so we felt that it was time that the community really 'owned' Django. Having the Foundation around pretty much guarantees that Django will stick around, even if any individuals or companies lose interest," he says.

Kaplan-Moss points out that the project now accepts donations for improving Django, and in the near future, the Foundation will primarily support Django through developer sprints, user meet-ups, and other community activities. Many development sprints will occur before the release of Django 1.0, and Kaplan-Moss says the Foundation will help key people attend sprints and work together. "If the Foundation helps Django move forward even a tiny bit faster, I'll be thrilled," Kaplan-Moss says.

Getting Started

Django is scheduled to release an official version 1.0 in early September 2008. For this article, I'll use the bleeding-edge code from Subversion, which should closely match the release. Your best bet is to install the official 1.0 release [4] when available or grab the bleeding-edge code from Subversion with:

svn checkout

Regardless of which version you choose, Django installs easily. While you're connected to the Internet, simply run the following as root

python install

to install Django into the site-packages directory of wherever your Python installation lives. For the example, I'll use SQLite as the database. However, Django has excellent support for PostgreSQL and MySQL.

To use SQLite, install the pysqlite2 package [5] and follow its installation instructions.

Django separates everything into "projects" and "apps." For example, if you build a large website with a blog, forum, and e-commerce section, the site itself is the project, and the blog, forum, and e-commerce code are apps. Really, this is just a way to organize sub-projects within your overall project.

To start a new project, run startproject mytwit

which creates the directory mytwit with a few initial stub configuration files and tools. Now you need Django to generate the stubs for the example app, which I will call Twit. To do so, run from inside the mytwit directory:

python startapp Twit

In mytwit/, set DATABASE_ENGINE = 'sqlite3' and DATABASE_NAME to the full path to mytwit/twits.db, the SQLite file in which your database will be stored. The full path depends on the directory in which you ran the initial startproject. So that you don't have to revisit again, you must add two items to the INSTALLED_APPS list: django.contrib.admin for the admin interface and the mytwit.Twit app. If you add to the end of the list, make sure you add the trailing commas.

After defining the database you will use, you must build your Model, which is a Python object that defines the SQL tables and columns and their relationships. Because your simple application has only one table, just define the one class. Thus, mytwit/Twit/ should be as shown in Listing 1.

Listing 1


01 from django.db import models
03 class Twit(models.Model):
04     date = models.DateField(,Date')
05     entry = models.CharField( max_length='500' )
07     def __str__(self):
08         return ,%s %s' % (, self.entry)

First, import the Django model helpers and then define your Twit class, which will contain a date column and a text column for your actual entry. Then define the special __unicode__ method, which tells the Model how to display an instance of the object in string form (in this case, just print the date and full entry). This information is used by the admin when displaying listings of entries from the database. The empty class Admin tells Django that you want it to provide the admin interface for you.

To check what you've done, validate your models by running:

python validate

If everything is okay, it should return 0 errors found. Now Django can build the database tables. To do so, enter

python syncdb

which outputs several Creating table lines, some of which are for user/group permissions, others for the admin, and the final for the Twit table. At this point, Django also prompts you to create a superuser for the admin interface, but remember the username and password, which you will need later.

After successfully creating the Model and database tables, we need to turn on the admin interface. This is done by uncommenting the three lines in the mytwit/ file that was created when we ran startproject. The three lines are labeled telling you to uncomment them to turn on the admin. The file is how Django maps different URLs to different parts of your application with regular expressions.

Additionally, we need to create an file. In this example, we're just using the defaults, but this is where you could customize various aspects of the admin interface. For this short example, mytwit/Twit/ needs to read:

from django.contrib import admin
from mytwit.Twit.models import Twit
class TwitAdmin(admin.ModelAdmin):
     pass, TwitAdmin)

To see it in action, run

python runserver

which runs a test server on If you need to run it on a different IP address or port, you can append that to the command with:

python runserver

Assuming you're using the defaults, go to and you will be prompted to log in to your app's admin interface. After logging in, you will see the screen shown in Figure 1.

Figure 1: The Django administration screen.

Because you are building a personal application, you can ignore the Sites and admin sections for now and just click on the Add icon in the Twit box. Then you will see something like Figure 2.

Figure 2: Add information for your personal app.

Now you can insert data for your entry. Clicking Today automatically fills in today's date, or you can use the calendar widget to pick another date. Next, input text in Entry and click Save, after which you return to a page that lists all the Twits in your database. If you click on the entry you just made, you go to an edit/delete interface to make changes or remove the entry.

Playing is fun, but you should share these entries on the web with friends. To do so, you must add a view (a module that performs the logic) and a template (how data are presented to the user). If you are used to other MVC frameworks, in which the view typically refers to the template itself, this can be confusing.

To begin, edit your mytwit/Twit/ to contain a simple method that returns all of your entries in reverse chronological format (Listing 2). This defines the method alltwits, which grabs all of your Twit objects ordered by the date field and reverses them. Then it calls render_to_response() with the name of the template for the view and a dictionary that contains the data you want passed on to the template.

Listing 2

Reverse Entries

01 from django.shortcuts  import render_to_response
02 from models import Twit
04 def alltwits(request):
05 all_entries = Twit.objects.all().order_by("date").reverse()
06 return render_to_response('all_twits.html', { 'entries': all_entries })

After you're done with the view, you need to build the template. To make things fit better on the page, see my simple markup example (Listing 3) to get a general idea. To keep your templates separate from everything else, save this file in mytwit/templates/all_twits.html.

Listing 3

Building the Template

01  <html>
02    <body>
03      <table>
04        <tr>
05          <th>Date</th>
06          <th>Entry</th>
07        </tr>
08        {% for t in entries %}
09          <tr>
10             <td>{{ }}</td>
11             <td>{{ t.entry}}</td>
12          </tr>
13        {% endfor %}
14     </table>
15   </body>
16 </html>

As you can see, the Django template language has advanced features and is easy to use. Here you use a simple for loop to go through each Twit object you passed in from the alltwits() method and to display the data via the date and entry methods on each Twit object in entries.

Now configure Django to find your template on the file system and set up a URL that maps to the view. To set up template directories in mytwit/, you must add the full path to the TEMPLATE_DIRS list, which depends on where you ran startproject (be sure to use the full path). Now edit mytwit/ to map the URL (Listing 4).

Listing 4

Map to the URL

01 from django.conf.urls.defaults import *
02 from django.contrib import admin
03 from mytwit.Twit import views
05 admin.autodiscover()
07 urlpatterns = patterns('',
08     (r'^twits/', 'mytwit.Twit.views.alltwits'),
09     (r'^admin/(.*)', ),
10  )

Here, you have imported your app-specific views, added a /twits/ URL, and left the default Django admin mapping alone. Now if you go to, you should see all of the Twits you entered in the admin interface.

Use of the standalone server and SQLite is great for quick development, but if you want to build a production app, you should switch to Apache, mod_python, and a more robust database such as PostgreSQL (see the Django site). Thanks go to Jacob Kaplan-Moss and Adrian Holovaty for contributing to this article. Code listings can be downloaded from [7].

The Author

Frank Wiles is the owner of Revolution Systems (, an Internet infrastructure and web-development consultancy specializing in scaling and performance-tuning open source software.

Read full article as PDF:

Django_Web_Framework.pdf (394.91 kB)

Related content


  • Thanks!

    We appreciate all the feedback and updates!
  • Django 0.96, vs. django 1.0, vs. SVN

    The problems you are running into are due to your use of the SVN version of django.

    In the past month many backwards incompatible changes have been made to the django svn and Django 1.0 was released just a few days ago. Due to the lead time on stories and the production schedule of this magazine, the examples and recent screen casts are for the earlier stable release of Django, 0.96.

    With that said, as you have found out it is relatively easy to upgrade the code examples to django 1.0.
    An exhaustive listing of all changes with instructions can be found here:
  • max-length vs maxlength present in

    Just one more. Seems to be something that people know about.

    Sorry for the noise.

    PS. I'll install from svn. DS.
  • Versionproblem maby?

    Must have to do with version. I did some grep in the installdir for django and found that max_length should be maxlength. When I changed that it came out with 0 errors.

    opensuse 11.0
    python 2.5.2
    django 0.96.2-5.5
  • Validateproblem

    I've just tried to go through the steps in this article. There seems to be some problem when I validate the code in listing 1.

    I get:
    mytwit.Twit: __init__() got an unexpected keyword argument 'max_length'
comments powered by Disqus

Direct Download

Read full article as PDF:

Django_Web_Framework.pdf (394.91 kB)


njobs Europe
Njobs Netherlands Njobs Deutschland Njobs United Kingdom Njobs Italia Njobs France Njobs Espana Njobs Poland
Njobs Austria Njobs Denmark Njobs Belgium Njobs Czech Republic Njobs Mexico Njobs India Njobs Colombia