Django at 30,000 feet colorful lead photo

Update 2017-11-01: This essay is quite dated; I'd recommend looking elsewhere for an overview of modern Django.

Ok, Mr. Framework, let's cut to the chase: are you going to solve my problems or not?

Far too many 'solutions' are more trouble than they're worth. Maybe I'm getting cynical in my old age (I'm 25) but my attitude is that if I don't see you solving the real problems that I know I'm going to run into, then forget it. The C programming language is a good example: if C wasn't pushing frames onto the stack and mapping variable names to memory locations for me, I'd have to be doing all that myself, in assembly. C solves a huge number of the problems that arise when write machine code, and all you need to learn is a few simple rules, not a giant framework.

But we're here to talk about Django, aren't we? Well then, let me state for the record:

Django solves my problems.

Before I talk about how, a caveat: my problems are probably not your problems. I have no web development experience, I'm working on my first site, but I never-the-less have a surprisingly good grasp of CSS and HTML (we use embedded HTML reports and controls in the application I work on) and I'm pretty good with Python. Plus, this site is an exercise in simplicity, nothing like a production system. So, this is not a recommendation for Django; just my high level impression of it. Still, it might be of some help to you in choosing the framework that's right for you.

Here's what Django looks like in my head:

Diagram showing the relationship between components.

URL resolution

Django solves this problem by allowing you to map regular expressions to views. It's pretty cool; you can use the regular expression "named group" syntax to pull out pieces you're interested in and pass them to the view. You can match only the first part of the URL and delegate the rest to some other URL handler. And lastly, you can provide an additional dictionary of parameters to the view, enabling significant re-use of views.

(r'^', include('site.mainapp.urls')),
(r'^static/(?P<path>.*)$', 'django.views.static.serve',
    {'document_root': 'home\media'})

HTTP Protocol

Django defines two classes, HttpRequest and HttpResponse, to handle the HTTP protocol. HttpRequest neatly exposes (but does not hide the difference between) GET and POST data. an HttpResponse object accepts an HTML string and builds the header for you; an optional mimetype argument lets you return any kind of content.

In Django, each request goes to a function that takes an HttpRequest object and returns an HttpResponse object. I like this; mathematically speaking, a page view is a function, so it's nice to see it implemented as one. (Functions in Python can be decorated and curried, which makes them a legitimate alternative to classes in many cases.)

Sessions and Authentication

Django stores a session id as a cookie, and stores the session state to the database. The middleware looks up the session state and provides a dictionary-like Session object in the HttpRequest. You can update the Session object, and changes are persistant. Quite familiar and intuitive, really.

The authentication functions builds on Session and maintains a table of users, permissions, and if they're logged in. The current user is provided in the HttpRequest. Any view can be decorated with login_required, which checks if the current user is logged in and redirects to a login screen if not.

I had approximately zero trouble setting up authentication sessions for my site, so from my point of view it's a "solved problem."

Model

The database (several are supported) is exposed through Models and Fields.

The Field classes, like DateTimeField and TextField, are used as properties of Models. Django uses introspection to automatically generate CREATE TABLE queries for the Fieldsin the Model, but altering tables with existing data has to be done by hand.

Models have a cute little API for selecting sets of objects from the database based on simple criteria. It's particularly interesting because it plays well with templates: even though templates have a very simple syntax, you can use this API inside templates without any trouble. It's definitely an '80/20' solution though; for complex queries you'll need to use SQL.

If you're thinking of going with Django, I suggest you examine the 'M' of MVC very carefully. While it's true you can swap in your own solution, that would mean giving up an awful lot of out-of-the-box functionality.

One thing I like is the complete set of ERD relationships between Models. One-to-one, symmetric, and other "special case" relationships are taken care of.

Templates and Filters

Django provides a templating system that can be used to separate the design from the code. There are two nice features of Django's templating system:

  • You can define filters in the template and pass the value through the filter before including it. They supply useful filters like escaping HTML characters and truncating to a short length, or even expanding alternative markup languages like Markdown.
  • Templates can inherit from other templates, and the child only needs to define the blocks it wishes to handle differently.

These features are not unique, but are cleanly implemented.

Templates don't have a complete language; but it does support looping and conditionals. You should carefully consider other templating solutions; there are plenty to choose from. Unfortunately, Django's templating system is coupled to the generic views, so you'll have to write your own views if you want to go with an alternative templating system. Unlike for the database API, this isn't a deal breaker; I believe you could use Django efficiently with another templating system.

Mental Model

Web development is fundamentally simple, and you already have a good mental model of what's happening: GETs, POSTs, cookies, mime types, and so on. My impression is that instead of trying to hide details you already understand, Django builds on that mental model and simply supplies the tools that you'd have to write yourself if you were working at a lower level.

Consider a class like DateTimeField: it can display, store, and parse dates. If you were working with CGI, you'd probably end up writing a similar class yourself.

That's mostly what I like about Django; it seems to follow the mental map of web development that I already have, providing neat solutions every step of the way. Your mileage may vary, of course.

- Oran Looney April 23rd 2007

Thanks for reading. This blog is in "archive" mode and comments and RSS feed are disabled. We appologize for the inconvenience.