Alcides Fonseca

40.197958, -8.408312

rails vs django

Lately I’ve been discussing the differences between Rails and Django with brecke, since he’s been learning Django now that he already knows Rails. After this post by Jared I decided to write my view about the main differences. Please note that I have not done serious development with Rails, only Django, so if I’m mistaken somewhere, do correct me.

MVC vs MTV

Django call their separation of domains MTV (model-template-view) instead of the traditional MVC. Using template instead of Rail’s view seems more obvious to me. And their reason for using another TLA is fair: the MVC pattern does not fit exactly in the rapid web development. Please see the Snakes and Rubies talk for more detail on this one. To me, the template word makes it clear I can’t have presentation logic there and it has to be in Django’s views, while the traditional View can have presentation logic. But in the end, code is not supposed to be in views/templates and you end up using helpers/templatetags to do that. So despite my preference for MTV, Rails does it right, and uses the name everyone else uses.

Convention over Configuration vs Configuration over Convention.

Specially if you have a J2EE background, you love the fact that Rails apps almost don’t have configurations. You just start coding, and if you follow some conventions, lots of magic is done in the background that makes your stuff just work. I believe this is what gave Rails the popularity is has today. With this stuff it is super easy to make 5, 15 or 30 minute screencast and get a full app working.

Django is different. While Rails feels just like Ruby with all that magic, Django reflects the pythonic explicitness. Just like in Python you have to declare the self and the first argument in a function, in django you have to say where your view (or model) lives. This is not a bad thing. It allows you to have reusable apps and other stuff, and makes Django loosely coupled.

In Rails brings a full stack to your development: activerecord, erb, prototype&script.aculo.us and you can do your full app almost just using Ruby. You write your databases in a ruby DSL, you write your Javascript in rjs and you can even replace erb with haml and write HTML in another ruby DSL. This makes learning web-development much faster (and maybe that’s why most rails users are students1). When developing in Django, you really must know your way around HTML, Javascript, CSS (and Ajax). Of course in Rails you can do it the raw way too, I tried it once, but it was not the 37signals way of doing it.

But being loosely coupled is the point where Django gets advantage. There’s no preference in your js toolkit. Some use Prototype, others jQuery and others even Dojo and mootools. And although you have Django ORM as the default setting, you can easily (and pythonicly) start using SQLalchemy just like you can dump Django Templates for Jinja2. And this is easy because Django is explicit. This is why I believe hardcore rubyists aren’t using Rails but Merb, that gives them the freedom of using whatever they want (Thinking about DataMapper instead of ActiveRecord) depending on their needs, and not using a cannon to kill a fly. Luckily Rails is merging with Merb and this will change in Rails3.

Migrations

Rails provide a default migration mechanism while Django doesn’t. There are a few options, but none of them was chosen yet. There are a few alternatives, because there is a need for a system like that. I believe it is handy sometimes, but I don’t really get. I believe it’s something version control (together with backups, so you don’t have issues) should do. I don’t like the fact that you have a database schema that is not consistent with your code. I admit however that this is useful to ease database administration in servers when upgrading the production environment. One point to Rails, just because there isn’t a default choice in Django yet.

Environments

This is a feature that comes out of the box in Rails and doesn’t in Django. Like I’ve said before Django is explicit, and you can make your environment system. Sometimes I don’t even use it. Sometimes I choose my environment depending on the machine name, and others depending on environment variables. It’s just an if and an import, no big deal.

Reusable Apps

This is where Django really steps up from Rails. In rails you can reuse code by using plugins, while in Django you can have reusable apps. For instance, I am developing a website, and it needs to have a forum. I just download django-forum and route /forum to forum.urls and I’m done. Same for any other thing, just like registration, profiles and other common stuff. And each app has it’s own views, templates and models. And you can write your own website splitting it into apps. Makes sense in not-so-small websites. Rails has plugins, that will extend your app, and not work independently. You can do the same as you would in a Django app, but not as clean and independent.

Admin

Django features a sweet admin system, that making development of simple CMSs really easy. This is not something you can’t achieve with Rails (and there are cool plugins to do it), but doesn’t really comes out of the box and integrate with different apps in your project. And you can even make your own website just by using django admin interface and authentication system. Is not a big plus, but counts a little towards Django.

Community

Rails is more popular than Django, and while it’s not actually older, it is only in 1.0 while Rails is 2.2. I don’t see this a downside because Django guys are perfectionists and Django 1.0 is way more solid than Rails 1.0 was. However in the time it took to reach 1.0, startups and other companies were adopting Rails and this has led to an enormous Ruby community. In my point of view, this doesn’t matter to me a lot because people using Django are hardcore programmers and know their stuff. You don’t get as many rookie posts in blogs as you’d get if you were looking for rails. But in the end, adoption rate matters in business and Rails wins there.

Outcome

While Rails seems more simple is magically, while Django requires you to explicitly declare some stuff, the latter is my choice because of reusable apps. Everything else (that I mentioned here or not) doesn’t really matter. Things are possible in both frameworks, sometimes easier in one, sometimes in the other.

Other resources

1Scroll down the Terry Chay rant until “Why I wish summer never ended”