Rails versus Django

January 21, 2009

The following is an email sent to a friend who asked which I prefer, Rails or Django. He chose to ask me since I had used Django almost exclusively at Cuker Design for over a year, and afterwards moved onto working for Slicehost, where we use Rails almost exclusively.

Sorry this got pushed back for quite some time. I attempted to gather my thoughts into some elaborate explanation, delving into the subtleties and intricacies surrounding the question. However, upon reflection my response is a simple one and should be taken lightly.

While it is opinion, I offer my expertise in using both frameworks, but I do not wish to imply any great importance to that factor.

Officially, I prefer Python as a language. I like its simplicity, terseness, the indentation-sensitive nature. Python is absolutely explicit and minimalist, where Ruby is implicit and feels flashy and loose. Python doesn't allow monkey-patching; Ruby does. Depending on your stance this is usually a good or a bad thing. For me, I'm on the fence: overriding methods is bad practice, but adding them is usually harmless.

From each of these paradigms comes a framework with the same look and feel of the language, for the most part. Django is quite explicit. A Django controller (using Rails' terminology for the clarity of argument. Search "Django MTV" for an explanation of how Django is "different" than MVC) is simply a function or method and does not have any implications, except that it must return a proper response object (or raise an exception). With Rails, implications abound. An instance variable (@foo) is accessible as a regular variable in the template. Idiomatically, a controller is matched up to a model and REST is used. So Controller methods show, update, destroy and create match up to HTTP's GET, PUT, DELETE and POST. Django, in this regard is almost entirely non-restful, which is not to say it is not possible. Django uses the more traditional separation of parameters in its request object, you'd use request.GET and request.POST to access the separate params. Rails, however, puts them all into the params method, which is usually okay due to its RESTful pattern.

These are the sorts of differences seen in both stacks. They are common, and commonly pivotal to arguments comparing the two frameworks. Proponents of one framework typically argue one way "because it is the way decreed by our language authors". So really you're looking at which language you prefer.

I write that last sentence with hesitation, as I have not used Django professionally in some time. They have since made a number of changes I disagree with, and the project's inertia has turned it into something of a monster. It is a surprisingly efficient and clean monster, but a monster nonetheless.

In playing around with Python and its WSGI spec, I created a micro-framework called Newf. I don't intend it to be a competitor to Django, much as I don't intend my ORM, Autumn, to be a competitor to SQLAlchemy, and the like. My reason for creating such projects is to have a simple, fast interface to all that is necessary, and no more. Django originally embodied that for me, but no longer. That's not to say that it's a bad choice, just that I am highly picky. After all, gluing together Newf, Autumn, Armin Ronacher's Jinja (templates) and a couple other libraries took no time, and results in a full-stack framework that covers 99% of what I need it to do.

To further complicate the monologue, another curveball. I'm creating a new project for a nonprofit I am starting and I have decided to use Rails. The project requires some somewhat complicated billing code which is satisfied by the ActiveMerchant project. I haven't seen a Python competitor that comes close, nor do I want to roll my own when it is something that should be bulletproof.

Apologies for the length. I started this thinking it'd be a quick 100 words. Please feel free to ask any questions. I'm not sure how much I've clarified things, if at all.

I was hoping to, one day, prepare a coherent blog post about the differences between the frameworks, comparing them point by point with an objective stance. However, while attempting to write an email on the subject I realized that was not possible for me, and it's almost entirely unimportant. The simple truth is that they are both great and stable frameworks. Most people make the decision based on what language they prefer, and that's how it should be if you feel strongly about that language. If you don't then it is best to choose the style you most agree with. Despite this generally pervasive argument across the intarwebs, some people fight against one thing or another saying this is better than that, inciting a divisive flamewar that will likely be moot over the next revision anyway.

In the world of photography, this is the same as the fight between Nikon and Canon. Which is better, you ask one photographer and they will say Canon. Another will say Nikon. And yet another will say neither, because Leica is superior. What most people don't realize is this opinion is just that—an opinion.

Should you rephrase the question as "What camera system is best for me?" you will receive a more diplomatic answer almost universally: choose the system that has the features, ergonomics, and price point you want. The reason for this, of course, is that cameras and web frameworks are tools. If your tool doesn't work the way you want it to, you will resist it. This is why some people simply hate Django or Rails; It doesn't fit into their style or personality.

In choosing what you want to use, you should first define your goal. A Leica shooter will have a better chance of not being spotted on the street since her camera and lenses are smaller and quieter than the SLR counterparts. Conversely, a Canon shooter would do considerably better on a football field, since she has autofocus, a supremely fast framerate and lenses beyond 400mm.

My advice is simply to ignore the irrelevant virulence directed toward a particular tool. Find coherent analysis of the features (documentation is a good start) and compare from there. Your framework will not make your project any better or worse; It is simply a delivery mechanism. After all, a good camera does not a great photographer make.


Comments

Very thoughtful and well writtern.

Posted by Pratik Naik

I[m a little saddened to think that someone thinks that django has become a weighed-down monster.
I like it, and am so relieved after struggling with so many f'd up intricacies when using cakephp. What a nightmare (and the one of the cakephp creators who frequents the cakephp irc is an arrogant s.o.b. notwithstanding)

Posted by steve

Shame you had to publish that email at all.

Posted by huxley

I'd love to know what recent decisions have been made in Django that you don't agree with. Just curiosity, no agenda.

Posted by Carl Meyer

Thanks for the post.

The bottom line might be one sentence from your post:
"Most people make the decision based on what language they prefer, and that's how it should be.."

For me at least, it's Python -> Django.

Posted by Ahik

"Python doesn't allow monkey-patching;"

Sure it does. That's even where the term appeared, in the Zope-community in fact. However, in the Python community, we have always been aware that it's generally not a particularily stable way of doing development, and it has always been seed as bad and ugly.

I don't know if Django has become a weighted down monster, but it's clear that that's the path they had chosen. Django made a lot of the same bad decisions as Zope did, many years earlier, and the result is that Django is a monolithic blob, and Django development has been quite isolated from the rest of the Python web framework world. Mark Ramm of Turbogears seems to have shaken up things a bit with a talk at DjangoCon about that.

The future of webframeworks, at least within Python, are the modular WSGI stacks, especially the ones using Repoze, which today includes (or will soon include) Turbogears 2, repoze.bfg and Grok.

Posted by Lennart Regebro

What do you mean with: "Python doesn't allow monkey-patching" ?

Posted by vds

Pylons, anyone? If Django is perceived to be such a monolithic monster, how about the seemingly more modular Pylons?

Posted by laogao

I'm also interested in what parts of the recent Django development that you disagree with. It would be interesting to find out. As with Carl, I am simply curious.

Posted by Dave Jeffery

Forgive my ignorance, as my definition of Monkey-patching was slightly incorrect since it is possible in most circumstances. Monkey-patching by Guido:

http://mail.python.org/pipermail/pyth...

My assumption was that since you could not extend built-in types (like list and dict) then it wasn't *really* monkey-patching. Goes to show I have much to learn.

Posted by SuperJared

@laogao: When I started with Python web frameworks I started using TurboGears. But I quickly switched to Django back in the days of 0.92 when I realized how much better I liked it. The alternatives that exist today don't appeal to me including web.py, Pylons, and web2py.

@Carl, @Dave: For me, newforms and the newforms-admin set of changes feel obtuse. The ORM has gotten bulkier when I want it to get smaller. The Q object is a bit weird, too, but that's been around for a long time. I had hoped that'd be changed in 1.0. The signals refactor doesn't seem to add anything significant. A few other minor quibbles here and there.

That said, nearly everything else is a boon, like the better unicode support and the auto-escaping of templates. And I will reiterate this is *just my opinion*. The issues I have with Django will not cause me to abandon it, especially for larger projects.

Posted by SuperJared

Unlike most of the people who have commented from what I can tell, I'm mostly a Rails guy. I started out doing PHP (back right before and as 4.3 came out) and then stopped doing that for a while, then got a job doing a lot of Perl coding. I was able to shift most of that to Ruby when I learned it and found out how much more I like the language. I've read about Python, but I haven't coded anything in it yet. I do see differences in the languages (of course) but not so big that I don't think they can both learn from each other, and I appreciate how, both being open source, libre software, they allow me to learn them both, without forking over a huge sum of money, and with the understanding that they are free to learn from each other. THis is truly great. Especially for someone who likes learning for the sake of learning.

Posted by Carl

I don't understand your comment about newforms, I've used a number of frameworks (including Rails) and newforms is what makes Django stand above the rest. I can take or leave any other part of the framework (I have no particular affinity for the template language or the ORM), but the ways forms are done is amazing.

Also, what you say about RESTfulness doesn't make a lot of sense. The fact that a default Rails scaffold can roughly map to the 4 Http verbs doesn't make it RESTful. In fact, I would argue that the scaffolds produced by Rails (pre 2.0 at least) are one of the biggest causes of misconceptions about what REST actually is.

I'm a bit of a REST nut and it's one of the reasons I chose Django.

As you say, it's all down to opinions. But it seems you and I have the same priorities about best practices and we've still chosen different frameworks.

Posted by Andrew Ingram

@Andrew: What I say about REST basically maps to the idea that Rails emphasizes the ideas of URLs as resources, and uses the HTTP verbs; You can do the same in Django, but there is little or no emphasis put on it, nor is there a restriction on how.

Posted by SuperJared

But a default Rails scaffold actually has it's own URLs for deletion, create and update views rather than using the Http verbs to govern what action should be taken. The fact that a GET request could be used to delete something is quite frankly dangerous and is one of the things that put me off Rails. I know it's behavior that can be changed but it's not RESTful and therefore your starting point for making a RESTful site is no better than with Django, it's probably worse.

When I'm building a site in Django I am very careful to expose URLs as resources rather than activities or actions and I've never felt that the framework impeded my ability to do this correctly.

Posted by Andrew Ingram

A thoughtful and non-confrontational opinion-piece. Excellent reading, and helpful to those trying to make a choice between frameworks.

Though I'm a Django convert, I'm uncomfortable with virulent evangelising. So I was particularly happy to read your post.

Keep up the good work!

Posted by Mike Hurt

@Andrew, while that was true a while back, Rails now uses the http verbs by default for those actions (there was a change to the way routing was done a while back to enforce this.)

Posted by Carl

Jared,

Excellent post, and just the kind of thing I'm looking for.

Thanks,
Hank

Posted by Hank Racette

Just curious, how do you see ActiveMerchant (and Shopify) stacking up against Satchmo?

I'm trying to build a simple eCommerce site, and was wondering if you've tried both.

Posted by Aneesh

Aneesh,

It's hard to compare the two; Satchmo is an installable project which you are free to hack, and Shopify is a hosted solution. That said I've seen serious issues in Satchmo, for example a friend's project using it ended up using something like 2000 queries in a single page, due to its inefficient method of sorting through product categories. If it's gone through a bit of efficiency-related changes I would suggest using it since you can literally do anything with it.

Posted by SuperJared

The way that the Rails router and default scaffold work are completely *un-RESTful*. You shouldn't be able to alter resources with a GET request. If you remember when Google Accelerator was released, all the Rails developers were crying about records in their products being deleted because of the pre-fetch feature. All that the accelerator was doing is issuing GET requests to links on the page, its the crazy way that Rails sets up the default that is at fault.

That being said though, a Request object should have both query string and content vars aligned together. Calling them GET and POST variables is *wrong* as a POST can use both query string and content, and a GET can use query string.

PHP also suffers from this with $_GET and $_POST. Rails gets that sort-of right.

Posted by Nik

Nik: Your comment about Rails default router and scaffold being unrestful is at least a year behind the times. As someone else has pointed out, Rails scaffolding has been very RESTful for quite some time. Even if it wasn't, few serious developers use built-in Rails scaffolding; it pays to dig a little deeper of the tools the platform actually offers you... the whole Rails community has come to virtual consensus on the importance of REST principles and Rails 2.2 embodies this consensus very well.

Furthermore, "you shouldn't be able to alter resources with a GET request" doesn't really make any sense to me... whether or not you write your applications this way is your concern. Obviously it's a bad practice, but what is Rails or any framework supposed to do from preventing you from executing an SQL DELETE within an "index" action method invoked through GET?

Posted by Ben

Nik and Andrew: at least get your facts straight. What you say about Rails' RESTful-ness is complete BS.

Posted by ste

Could the Leica users be analogous to Lisp users? A platform/language that is perceived as antiquated, but in it's element is supremely powerful and expressive...

Posted by Mark Menard

To ste: If that is all you have to say don't bother. If you want to actually join the discussion and explain WHY then that's great. Calling someone else's comment BS without an explanation is just ignorant blather.

Posted by Rick

I really like Python and I love Werkzeug.
I think it's not very well known (http://werkzeug.pocoo.org/) but I think it would deserve it.

Posted by Bastian

Hi ya,

There is no need of ruby language if you can write clean code in perl. Also, try developing a framework(full/part) in perl that suits your work and automates things you want.

Still perl is fastest among perl, python and Ruby(1.9).

Python
-------
Python as a language sucks due to lack of
a) speed.
b) private - public - protected vars/methods.
c) Threading clarity.
d) Incomplete OO ness.
e) Good documentation.
f) Need for extending it. (Shud I learn one more lang??)

But Django and pylons are wonderful tools. Wx python is average tool for graphics. Swing is better.

Ruby
----
Ruby is a great language with lot of cleanliness, OO completeness and speed too with 1.9 version. But, there are too many short cuts and I don't like implicitness.

Ideal Language
--------------

In short, I want a language with the features:

1) Loose typing
2) Threading option
3) Superior Graphics and statistics modules (not so imp)
4) Least run time
5) Shorter development time
6) No need to extend the language in any another lang.
7) Good OO ness (like in Ruby).

Ideal Framework
---------------
I want a framework like Pylons with solid documentation.

The End,
Sam.

Posted by Sam

@Mark Menard: Haha!

On the subject itself: This is starting to be like one of those linux/windows "discussions". I personally, without really having used either professionally, prefer django for its cleanliness and straight-forward "this is right, that is wrong" attitude. That's because I'm not really a developer, if not more of a designer/architect, so it keeps me on the track.

I've only used CakePHP in a couple of projects, and that was probably enough of the railsy world for me, Django instead is (also after a couple of projects) only growing on me.

Anyway, matter of opinion, as you said. I need to check some other python frameworks also..

Posted by Osku Tervonen

@Sam: you should see FalconPL

http://falconpl.org/

Posted by John Miles

Thanks John I am palying with falcon now

Posted by Sam

Love the camera analogy.

Posted by SeanR

I think my biggest frustration with Rails was, I like to learn from books, however a lot of the Rails books out there target 1.2.x, and don’t appear to have been updated for Rails 2.x, as such I found myself needing to Google things frequently when code in the books didn’t work as expected.

Django on the other hand seems to have maintained pretty good backwards compatibility from 0.9.6 right through to the 1.1 release. Not perfect backwards compatibility, but enough. Also most of the Django books seem to have been revised for 1.1 including Practical Django and The Definitive Guide, both of which I found to be invaluable resources.

I have more recently been tinkering with Grails, which looks quite promising, and is definitely worth a look, especially to anyone with a Java background www.grails.org.

Posted by Mitch

jpnseq, 2515, :-(, 7880, :-(, 078, 214914, 887, ghejr, >:-DDD, =P,

Posted by most beautiful women

2TI4Yf Guexvn yiat acin mjwi ifmw fxearkbor cycz wyevdirsco oifjyqvnx.

Posted by Dszmhhbf

Add your comment

No HTML; Only URLs and line breaks are converted.