Kenneth Arnold. The series, Wielding Django, looks at stripping the complexity away from Django so that it is easy--perhaps even PHP-like--to use it for small projects."/> Minimalism


June 11, 2008. Filed under django 72 python 59

( This is the first of a multi-part series written by Kenneth Arnold looking at using Django with less of the sometimes imposing overhead that comes with it. I'm excited about this series, and to be working with Ken. Now, without further ado, on to the content. - Will )

For most of us, a sword is a heavy metal stick with a weird handle. I probably couldn't even cut a shrub with one. But wielded by skilled warrior, a sword is a powerful weapon.

Likewise, Django (and even Python!) can seem big and clunky. But in skilled hands, it's agile enough to level the shrubs of web development while strong enough to take on larger foes as well.

The goal of this mini-series is to help you wield Django to do your wishes. We'll strip down to the bare minimum and build up from there. Along the way, we'll take a few unconventional turns to build your agility in AJAXy, "Web 2.0" apps.

If you have used Django before, you should be able to easily skim the first two articles. Come back and join us for #3, where I'll be introducing django-webapp. Go ahead and check that out; comments appreciated.


  • We'll be using the Django SVN (the "development version"). Get this set up according to the
  • I develop using Python 2.5, but it should work on Python 2.4 without modification. Python 2.3 will require a few more changes (particularly, decorators).
  • Use IPython.
  • Remember: Django is Python.

Minimal Django

The Django tutorial starts you out with a broad overview, which works great for showing you one way you might use it in a big project. If you're the sort of person who learns best by getting the big picture first, you might want to work through the tutorial before continuing here. Instead of starting with the big picture, we'll practice a few very basic moves first.

Start out in an empty directory, with just the following in


You can probably guess what this does without even running it. Let's run it anyway. Bring up a Python console -- or better yet, IPython -- and tell it this:


Don't worry about the details of this last part; Django will give us a way to automate that. You can just notice that Django can use WSGI, which will be interesting when you want to deploy your app on a big server. That comes later.

Go to to get greeted by your first (or at least, your smallest) Django app. Now to the exegesis.

Django's main job is turning requests (from your browser) into responses. The most important part of a request is the URL, so that's the first thing we tell Django about. The line marked (1) in the shell code told Django that your ROOT_URLCONF -- the place to start looking up what to do with a URL -- is the app module that you just made. (Note that just like import app in plain Python, it doesn't end in .py.)

URL Configuration

A Django URL configuration module, like the one you just made called app, needs just one thing: a variable called urlpatterns (line (2) above). It pairs URLs with functions that get run when that URL is requested. When you request a URL from the server, the URL resolver runs through the list in order, looking for a match for that URL.

Okay, that was slightly a lie. Web servers rarely deal with the full URL, and Django is no exception. The URL that the resolver is trying to match is the path of the request. That's the URL in the address bar, minus the http:// and the server name, and minus any GET parameters (we'll get back to that). So if you put in:

then the URL would be just posts/. (Yup, no initial slash either.)

URLs are matched by regular expression (regex). If you've never heard of them, don't panic; they're a really powerful way to deal with strings, and worth learning for that reason alone, but we won't be using nearly their full power here. The regex that we used matches a string where the beginning (^) is immediately followed by the end ($), that is, the empty string. So it matched when we asked for And when it matched, it ran the view function that we passed to it. (Functions are objects too; Python's cool like that.)

You might find the docs for the Python re module helpful, particularly the syntax docs.


Views turn requests into responses. They always get, as their first parameter, an HttpRequest object, which everybody likes to call request. (The URL configuration can also pass some other parameters to the view. We'll come back to that.) We defined our view, called greet, on the line marked (3) above.

The single job of a view is to return an HttpResponse object. It's basically a string, but can hold extra headers, response codes, etc. In line (4), we just construct the response from a constant string.

And that's it! No magic here. Armed with this and a few bits of the Django docs, you could easily do any of that stuff you used to do in PHP. But stay tuned; Django can let you do a lot more...

Postscript for the screaming Django experts

Yes, I'm starting out with some very non-idiomatic Django. I wanted to start with the bare minimum of Django's abstractions; once you're used to them, switching to more complex things like, patterns, a separate, etc. should be an easy step. We'll take some of those steps as soon as the next installment.

Also, I think that using url directly, as I have here, is more explicit than patterns. But more than a matter of preference, it will actually make some things clearer in later installments. If you think this is a bad idea, tell me why and I'll be happy to change to match conventions.