First impressions of Django

Posted by Jeremy Voorhis Mon, 15 Aug 2005 17:58:00 GMT

Disclaimer:

I have been developing with Rails for a few months now. I like it. I’m familiar with it – I even like to think I know my way around the class library quite well. That’s expertise, something I don’t have when evaluating a new framework. I am also getting to know Ruby very well, from structuring applications intelligently to metaprogramming. Conversely, I’m a total Python newb. I also interact with the Rails developer community on a regular basis, while having no experience with Django’s community in any way. In short, there’s no need to accuse me of being biased – I know I am :)

I also did not complete the Django tutorial last night. I got through part three and decided to leave the rest for tonight, but I’m reporting what I’ve found thus far.


Django is an interesting creature. It simultaneously provides a lot more and a lot less than Rails for different tasks. It also has some key differences in its philosophy that yield some interesting results. I will try my best to compare and contrast the two frameworks.

Key similarities

  • MVC-style framework
  • Database-independent object-relational mapping
  • Template engine w/ embedded Ruby/Python
  • Code generation scripts
  • Tiny web server for development use
  • Mechanism for routing URLs

Django’s big ideas

  • Model definitions are complete – schema is derived from methods, not vice-versa
  • The application generates the schema – this is currently possible with PostGreSQL, MySQL and Sqlite so you can theoretically change your database vendor with ease
  • Dynamic admin – really nice CRUD screens are generated from the models, and they are related according to foreign keys. You don’t get that with scaffolding in Rails. The dynamic admin is available system-wide, with facilities for overriding the default templates
  • Generic views – generic templates for details and list views are installed system-wide This is a lot like scaffolding.
  • A project can have multiple applications which share a dynamic admin, but are responsible for their own configuration (routing, etc.). Yep – they’re pluggable.
  • User and group models built into the framework, as well as history – when you create a Django project, you get the benefits of the login_generator (with salt), an ACL, and acts_as_versioned out of the box.
  • The pluggable apps share the user model – single sign-in!
  • Django provides other large application chunks, such as frameworks for RSS as well as comments. I haven’t used these yet, but I can see them being useful for providing these features on top of my models

My experience

The first few minutes spent in the Django tutorial were really rewarding. Specifically, the dynamic admin thing is cool. It demonstrates some attention to detail and from what I’ve seen so far, it’s the sort of thing I would feel comfortable giving to a client.

As soon as I left admin-land, however, I began to miss Rails. Views (Django-speak for actions in Rails) aren’t automagically associated with templates (Django-speak for views in Rails). Instead, you write the code to glue them together for each view, passing the output to an HttpResponse object. The template system also lacks one feature I couldn’t imagine using Rails without – helper methods. Instead, you get “filters” which you pipe your data into with, well, the pipe character. Filters seem useful for formatting data, but they don’t appear to be intended for complicated tasks. On the whole, Django’s templates remind me of Smarty more than ERb.

The directory structure for a Django application is smushed – in the tutorial, models are all written in one file. I could see this becoming a nuisance if I accumulated a lot of model code. Another thing I have seen no mention of thus far is unit testing. I would be surprised if there was no unit testing framework available in Python, though, so I’m assuming it shouldn’t be an issue if you want to test your models yourself. Unfortunately, Django has no concept of distinct environments, so it may take some additional hacking to get the isolation of the test environment that I enjoy in Rails.

One thing I am liking about the framework is the pluggable applications concept. A Django project has many applications, and there are project-wide configuration files – one for routing and another that is like environment.rb. These files are Python and are governed by a similar philosophy to Rails’ Ruby configuration files. Within these files, you can provide some global settings such as a database connection, and delegate other settings to the individual apps. For example, you can chomp the first part of a url and pass the remainder of it to the appropriate app, which then manages its own routes. This should make applications very portable between projects.

Tonight I plan to finish the tutorial, and then kick Django around some – specifically, I’d like to see how the dynamic admin and the sql generation can cope with more complicated domain models.

Comments

  1. Adrian Holovaty said about 3 hours later:

    Thanks for the writeup! Some corrections and clarifications:

    > Views (Django-speak for actions in > Rails) aren’t automagically associated > with templates (Django-speak for views > in Rails).

    That’s a feature. It’s called “loose coupling,” and we like it. :) You’re free to use any template system you want with Django. Tying the views to use our own template system would be a design smell.

    > The template system also lacks one > feature I couldn’t imagine using Rails > without – helper methods.

    You can add custom methods to your model objects, and call these custom methods from your template. Because they’re in Python, custom methods can do very complex things, drawing from the rich Python standard library.

    > in the tutorial, models are all > written in one file. I could see this > becoming a nuisance if I accumulated a > lot of model code.

    Models don’t have to be in a single file. You can spread them over as many files as you’d like. Indeed, we use a couple dozen for ljworld.com, lawrence.com, kusports.com and 6newslawrence.com. The two models in the tutorial are in a single file for simplicity.

  2. Jeremy Voorhis said about 4 hours later:

    Adrian,

    Thanks for the feedback! I don’t think you quite understand the bit about helpers though – for example, I wrote a fairly complex model-agnostic databinding calendar helper for Rails – code like that certainly does not belong in a model. In fact, I can’t think of any helpers in the Rails framework that depend on a model.

    Rails also lets you provide your own template systems, but it expects ERb by default. There is also builder, which is meant for xml templates.

    As far as things like splitting models up between files, I’m sure it’s really a non-issue, but shouldn’t the tutorial demonstrate best practices? I personally don’t consider all models in one file a best practice.

  3. Adrian Holovaty said about 13 hours later:

    Hey Jeremy,

    You’re right—I have no idea what a “helper” is.

    But it sure sounds helpful.

    Anyway, that sounds like something that doesn’t belong in a model. Models can import arbitrary code, so building some sort of generic “helper” thing should be easy.

    As for splitting models among files: The tutorial does indeed demonstrate best practice. Having two models in the same Python module is perfectly OK, especially if they’re related to each other many-to-one. Generally we split models into separate modules when there are substantial differences between them. That’s a fuzzy reasoning, but you know it when you see it.

  4. Jeremy Voorhis said about 15 hours later:

    Yeah, there’s no reason Django couldn’t have some really nice helpers. One nice thing about helpers in Rails is that there are a lot of really nice ones. The url_for helper can construct a url based on a controller, a view and some params and is tightly integrated. The Ajax helpers write most of the Ajax javascript you’d need, in concert with the prototype and script.aculo.us javascript libraries. There are also useful helpers for turning <code>Date</code> objects into fuzzy human-readable text. Point is, there are a lot of useful ones and they work now.

    I think something like a helper library (or several) would go a very long way Django.

  5. Jeremy Voorhis said about 15 hours later:

    Another useful example of a helper is the <code>textilize()</code> helper that rendered the links in the above comment ;)

  6. Robin Munn said 1 day later:

    I don’t know Rails, but I think the Django equivalent to Rails “helpers” would be either filters or custom tags. It’s not too hard to write custom tags (which would look like “{ my_custom_tag }” when invoked from templates).

  7. Wilson Miner said 1 day later:

    Jeremy, you mean like this ?

  8. George Moschovitis said 1 day later:

    From what I am reading, Dango is more similar to Nitro than Rails. Nitro is another Ruby Web Framework (http://www.nitrohq.com)

Trackbacks

Use the following link to trackback from your own site:
http://www.jvoorhis.com/articles/trackback/14

(leave url/email »)