( 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
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
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
Start out in an empty directory, with just the following in app.py.
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 http://127.0.0.1/ 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.)
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
http://127.0.0.1/. And when it matched, it ran the view function
that we passed to it. (Functions are objects too; Python's cool like
Views turn requests into responses. They always get, as their first
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 settings.py, patterns, a
separate views.py, 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