I have to apologize for mentioning Rails in the first sentence about Django, but Django should really take some cues from it. Promised to check out Django when I got a chance and due to some clever persuasion I managed to convince my coworkers that I should be the one to model some information and that I should use Python to do it, so I took a swing at it. Django is about a million times more hip and a bit easier to use than any other Python web frameworks I have checked out, and while it only barely competes in a Rails world, I think it could grow into the shoes it needs to fill.
I’m pulling out a classic review format for this one.
The Good
Python. Python is such a beautiful, beautiful language, kicks Ruby’s ass almost any day. Ruby has a few constructs I quite enjoy, but in the end a Python script still carries the readability much further. I can still remember the smile on my face when r0ml said “the difference between poetry and prose is whitespace.” Python is a stronger language even if Ruby has some strong libraries.
The admin interface. A little bit overkill for a fair portion of tasks I might want to build a website for, but it is a nice tool to have nonetheless. A scaffolding style generator would still be nice for making front-end database interactions breezy, but it is comforting knowing that there will be something to admin there regardless of what the front-end looks like.
The attitude. Django is a nice project, they tell you things that they think you might find useful, they treat you like a programmer who knows what things mean, they tell you how what you need to know to install a version from svn and keep it up to date.
Using regular expressions for url routing. As much as I like how smart Rails is about generating urls, I constantly ran into situations where I could have routed the damn thing with mod_rewrite more usefully than with their system. I certainly have a penchant for experimental and complexly defined url structures, but Rails never gave me enough freedom. Django gives me the freedom I want although it comes at the cost of being able to easily generate urls.
Middleware, request objects and sessions. Haven’t actually delved into these much yet, but from the looks of the docs they seem to be nicely featured.
The Bad
Configuration. Why do so many things need to be configured everywhere? Sensible defaults are the key to making things easy. Take the admin interface and the project from the tutorial with polls for example. Most of the time that I am using a model with a created_date property plenty of things can be inferred: the default date when creating an item should be now, you shouldn’t be expecting to change the date and you probably want to be able to sort by the date. Those things should all just happen, it is the most common usage, the defaults can be overridden if need be, but making me add
class META:
admin = meta.Admin(
list_filter = ['created_date'],
date_hierarchy = 'created_date',
)
and still not even auto-filling in the current date when creating is bullocks.
Adding projects to the global search path. The install instructions suggest you add your project to the site-packages directory (I suggest you at the very least keep things in one spot and add a djangoprojects.pth file to your site-packages directory with the proper paths in them), but this is still a step that is ludicrously costly when it needn’t be. I haven’t hacked a fix in for this yet, but believe me I plan on it. This is nice when it comes to importing things in the interactive interpreter, but could be done pretty much as effectively through a smart module like django.projects and some fancy namespace magic.
Template paths. Give me a goddamn templates directory by default, make that directory a default directory in the template search path, put sample templates in there for me to edit when I create a new ‘app,’ don’t make me generate a Context object to send to the template (how hard is it to just default to using locals()?), and don’t make me load the template_loader class. I am writing a web site, I am going to use templates, don’t make me tell the system “oh, I’d like to use some templates now, please,” let me say, “hey, no templates this time please.” Of course I want fries with my burger, I’d tell you if I don’t.
The Ugly
django-admin.py. Wow, way to make something annoying to use. Remember that stuff about convention before configuration? This is the perfect place for it. I got so tired of this after a couple tries (no, I will not change my environment variables for you, Django) that I patched the script to make it work in a sane way.
To see a quick hack for this grab my hacked version of django-admin.py or just look at the diff (if you want a more effective patch that solves a couple other issues like this one, check out my modifications in my svn for Django, they are better than this hack but require more than a simple diff). Here’s how it changes things:
Before, I could make a new app in a project by going into the app directory in that project directory and then calling a long command-line like
django-admin.py --settings=djangotest.settings.main startapp bugs
Uggggly. With just a quick hack, if I am anywhere above the base project directory djangotest the script will find the settings file for the project and find the apps folder in the project. Convention over configuration. Sure, I could add some big long variable to my environment, but chances are if I am in my project directory that is the project I am talking about, the script should figure it out.
My little mods also, by the way, allow you to say
--settings=admin
and find the expected settings file if you want to run the admin stuff, or just put in a full path to settings if that’s your kick, but I assure you it isn’t mine.
Conclusion
I like Django’s feel, I like the ways it lets me define things but I hate how many things it makes me define. I hate the lack of effort put into making it effortless but love the effort put into making it pythonic. They’ve got good documentation, plenty of useful code, a slick website and some great ideas. Of the web frameworks I’ve tried, it comes second only to Rails, but it is still a distant second.
Boris tells me I’m supposed to check out Swat next.
Technorati Tags: code, django, frameworks, rails