Minimalism
( 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.
Basics
- We'll be using the Django SVN (the "development version"). Get this
set up according to the
instructions. - 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 app.py
.
qaodmasdkwaspemas0ajkqlsmdqpakldnzsdfls
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:
qaodmasdkwaspemas1ajkqlsmdqpakldnzsdfls
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
.)
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:
http://myserver.com/posts/?all=0
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
that.)
You might find the docs for the Python re module helpful, particularly the syntax docs.
Views
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 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
match conventions.