Saturday, December 22, 2007

Django : First Impressions

In my last post, I spoke of my experience with Pylons, a Python rapid web application development framework similar to Ruby on Rails, and drew parallels with popular Java frameworks I have used in my development work. An anonymous commenter expressed surprise at one of my comments where I said I considered TurboGears and Pylons top contenders in this space, and pointed out that Django has more people on its mailing lists and a longer list of deployed sites in production.

First off, let me say that I am no expert in Python frameworks. I happen to like the Python language, and use it for all my scripting work. I use Java for web development, and I picked up PHP again when I built a small application recently. However, I have admired Ruby on Rails for a while, but was too lazy to learn the Ruby language, so I was really looking for something similar in Python-land.

So anyway, when I looked at Django the last time around, I thought it looked kind of (too) optimized for developing database driven web applications. Also both TurboGears and Pylons leverage external projects for part of their functionality, so as a Java programmer, that approach appeared more attractive to me. However, I realize that I may have been kind of hasty in my comment, so I decided to download Django and run through the tutorial (which is a database driven app, but at least I would know more about it than I did when I wrote the comment.

The installation was completely painless. I downloaded the tarball for the latest official release (0.96.1) from the site, then ran

python setup.py install
to install it. I then followed a very informative 4 page tutorial to build a poll system with a MySQL backend. This includes a very pretty and functional admin interface, along with the user facing application itself. I won't bore you with the details, except to say that the tutorials are quite extensive and very detailed, and all the commands work as advertised.

Running

django-admin.py startproject ${project_name}
creates an empty project template for you. The template is sparser than a Rails project, it consists of just 4 files in the project directory. The manage.py is the super-script (similar to the Rails scripts in the scripts directory) that you will use to generate and run almost everything, which delegates to the manage.py program in Django's installation.

To run the application for development, Django provides a runserver subcommand for manage.py (

python manage.py runserver
) which instantiates a HTTP server at port 8000.

Application wide configuration is through a single settings.py file. Sub-applications in the webserver are stored as subdirectories, which are accessed through Django code as Python packages. Each such package can have its own settings.py file for configuring that package. To create a package, run the command

python manage.py startapp ${packagename}
, this will create a subdirectory with the skeleton code for models.py and views.py.

Django follows the MVC paradigm, however, the nomenclature used is somewhat different. Database tables are mapped directly to models in models.py, and the controller methods are declared in views.py. The actual views are in a template directory that is defined in settings.py. The templates contain HTML and markup in Django's custom templating language. So the MVC is actually MTV in Django.

Django's custom ORM is quite lean, and similar to SQLAlchemy in Pylons, and like RoR, has support for declaring and following 1:1, 1:n, and n:n relationships. Each database table is modelled as a class in the models.py file in the package directory. One sets up the database mappings in the settings.py file, then creates the model classes. Then we need to run

python manage.py syncdb
to create the tables in the database. However, I found the SQLAlchemy API more intuitive.

I particularly liked the Django shell, in which it is possible to interactively play with the models, adding and removing data, to see if everything works. It can be started with

python manage.py shell
at the command line.

The templating language is custom to Django. It contains most of the simple control structures you would expect. However, the impression I got is that the preferred way is to do as much processing as possible in the controller layer (methods in views.py), which is what I would prefer to do in any case.

Overall, I liked Django. It is very similar to RoR, probably more so than TurboGears and Pylons, in the sense that it is a custom full-stack application optimized for database-driven apps. Django's routing appears to be slightly more advanced since regular expressions can be used to specify patterns, but clean URLs can be constructed by both frameworks. Pylons generates a nicer directory structure and uses (in my mind at least) correct nomenclature; however, that is probably just a function of usage.

From browsing the net, it seems that there is a stronger following for Django than for Pylons. Comparisons between TurboGears (and by extension, Pylons, which is very similar) and Django seem to favor the latter. However, there seems to be a dedicated following for Pylons as well. I found both Pylons and Django to be equally effective for my purposes, although I found Pylons to be more Java like, and thus more intuitive. Both offer functionality similar to RoR, which is great news for Ruby-challenged Python programmers like me.

And to the anonymous commenter, thanks very much for pointing me to Django.

Be the first to comment. Comments are moderated to prevent spam.