portable perspectives

a blog about programming, life, universe and everything

Rails vs Django: a non biased yet useless comparison

Lately I've been making my hands a little bit dirty with django, and since I already did a little bit of Rails I think I'm entitled to do a small comparison. No, this is a lie. I'm entitled to do that because I have a blog and that's it.

The non biased assertion is due to the fact that I like both frameworks and I do love both languages, the useless one is well, because you will still have to evaluate the things by yourself , cause I am not an expert at either and I think that my few readers are smart enough to understand that choosing an infrastructure requires more work than reading a random blog entry.

Both frameworks use the new classic MVC pattern (even if in django's lingo it's called MTV you will notice that it is 99.9% the same), and both framework provide some othe features, so I'll just split the comparison by these concepts.

* Model * The model layer in django and rails is basically built out of classes that map to DB tables, but the things are slightly different.

The model in rails is comprised of two things: an SQL definition and a Ruby definition. Yes I know about Dr Nic's magic models. You can also create the database in pure ruby by using the wonderful migrations' system that rails provides, but the model is still built out of the pair DB structure + Ruby code. AFAIK django doesn't have yet something on the level of Rails migrations, that allows you to programmatically move back and forth in time easily.

Django uses a single definition in python with more metadata, and provides some useful python datatypes that are mapped transparently on the DBMS, so that a Post class can have a SlugField, while a Comment can have EmailField and IPAddressField. Yet, you can still go down to the SQL level if you want.

It seem to me that the support for validation is quite similar under the surface for both frameworks: you can validate single fields ot whole objects at different times and stack different validators.

One big flaw in current django's models is that they don't allow inheritance, and so if you have a lot of models that differ just slightly you can't save work using this approach. Rails' ActiveRecord gets a big plus for this, but this should be solved soon in django.

* "the thing that does *which" ** Rails calls the module that chooses which data to show the Controller. For some reason Django calls it the View whereas the Controller is the underlying support software.

Rails which is made of two elements: Controller objects and actions. A request for a page is processed so that it instantiates a Controller object and setups variables appropriately, then the action method is called. At the class level you can define behaviour shared between the various action with a nice syntax, but I don't particularly love the :except and :only things.

In django an action is just a function which takes a fixed argument, the request, and an optional set of named arguments. I love the way named arguments work in python and I think that this approach provides much more readability, but to have that in ruby we will have to wait for ruby 2.0 (or use evil.rb which doesn't feel enterprisey).

The only thing I dislike in django's view is that you have to explicitly point out to a template file when rendering a view, whereas rails' convention over configuration in this case relieves the user of a repetitive and non-interesting operation.

I also think that not having the class Foo < Controller boilerplate is better, but the bad news is that django doesn't do magic requiring of modules and you have to do it yourself, so everything balance out.

Both systems allow caching but (for what I understood) Django mostly uses time-based cache invalidation, while rails provides only an event-based expiring behaviour.

Anyway there are plugins for rails that allow time based invalidation, and I believe that it should be possible to expire something in an event-based fashion in django too, cause the underlying mechanics are the same (CACHE.set(key,val), CACHE.get(key) and CACHE.del(key)).

It seems that django doesn't provide the fine-grained caching control that rails has, allowing just a whole-page caching or forcing the user to resort to the low level cache api, which I think is a bad thing.

Finally, django uses exceptions to handle error codes, which I believe is a far better solution than rails :status=>code, because it allows breaking out of an action from an utility method. This allows, the refactoring control in utility methods, having shortcuts such as get_object_or_404(Class,key=val), which simplify the writing of views.

* "the thing that does _how_" * The actual showing of data is usually done in both frameworks through templates, which rails call Views. Django uses an interestint template language while rails uses ruby embedded in XHTML by deafult, but different templating engines can be used as plugins very easily.

Both allow the composition of smaller units to enhance reuse and ease of maintenance and it I believe that apart from personal preferences there are not big differences in this area.

* Other things * I think that the main differences in rails and django can be appreciated going away from the basic elements and looking at the rest of the platform, where the frameworks differ greatly.

First, django provides internationalization as a builtin concept while in django you're forced to use external libraries such as Globalize. Sadly, I am convinced that this is such an important feature that it must be builtin and it is an error not to have it, because to do it right the framework must be engineered around it. It must be also noticed that python's support for unicode (and other text encodings) in general is far more advanced than ruby's, which basically just kind-of-supports utf-8 (wait for ruby2, again).

Second, django's automatic generation of an administration facility, complete with authorization support and a bunch of space for customization is amazing. Again, there are modules for rails that provide this kind of behaviour, but having such a feature builtin makes it a foundation and a reference against which every programmer can code, which makes coee sharing easier.

In general django has builtin support for a lot of functionalities that are common in modern web apps, not only admin and auth, but also sitemaps, syndication, comments and much more.

Rails takes a minimalistic approach on this and pushes all this stuff in plugins. The rails community is producing plugins at an incredible rate, and even if not all of them are compatible and high quality code there is a lot of choice.

In the old days rails' plugins used to have some issues and this was the reason for the existence of things like rails engines but as of 1.2 this problems are not there anymore, Django allows code sharing through the integration of different apps which is what the admin above mentioned features are, and each of this add-on can contain something as easy as a textilize() function to a whole application such as a wiki or a blog.

There are not so much django apps as there are rails plugins, and I believe that this depends on 3 factors

  • smaller community
  • slightly harder sharing (in rails you just user script/plugin install and you're done)
  • less duplication The latter is hardly dependent on django coming with more batteries included, so for example you don't need a plugin for creating slugs because there is a lready a slugify() function.

* Conclusion * I wish rails had more batteries included, and that ruby was a little bit more like python (i.e. modules, named args, function decorator syntax). And I wish django used more conventions/less typing, and python was more like ruby (blocks, functions call without parenthesis, implicit self). but I still like both, pick your choice or even better try both. This at least will make you ready to write your own framework ;)

See all comments

AddThis Social Bookmark Button