top | item 2670697

Django 1.3 vs Rails 3: A not so final showdown

103 points| bozhidar | 14 years ago |batsov.com | reply

80 comments

order
[+] Spyro7|14 years ago|reply
"Some of you probably know that Python is currently at a bit of a crossroads. Python 2.x was the stable Python version for many years, but recently it was replaced by Python 3.x."

Python 3 has not "replaced" Python 2. The reality is quite a bit more nuanced than this, and it is hardly a bad thing that Django does not support Python 3 right now. To give this section the heading of "The great divide" is just a tiny bit hyperbolic.

From the top of the python.org page dedicated to the subject[1]:

Python 2.x is the status quo, Python 3.x is the shiny new thing

Also from that same page, here are some of the key things in Python 3 that are not in Python 2 yet:

* function annotations

* syntax for keyword-only arguments

* extended tuple unpacking

* non-local variable declarations

There is nothing in this list that a developer must have in order to develop their app, and there are no Python 3 exclusive projects that do not work with Python 2.

The fact that few major Python projects are currently ported to Python 3 is not evidence of some tremendous looming problem in the Python language. It is evidence that Python 3 is only, really, an evolutionary transition from Python 2 and that this transition has a long time horizon.

The move from Python 2 to Python 3 is nothing like the move from Ruby 1.8 to Ruby 1.9. There are no dramatic speed or stability improvements that make Python 3 something that is terrible to miss out on, and there is no rush to get projects ported to Python 3. It will happen when it happens.

[1] http://wiki.python.org/moin/Python2orPython3

[+] dgallagher|14 years ago|reply
I agree with you. Before there's a need for Django to be on Python 3, there must be a major need that Python 3 serves which Python 2 does not.
[+] rbanffy|14 years ago|reply
I cringed when I saw him installing Django with yum. That's the surest way to end up with an ancient version.

You let the package manager manage whatever you are not very interested in (something you don't care with recent version you are running). I'd never let it manage something I can manage better.

[+] po|14 years ago|reply
Absolutely. It's ok if you're installing Django to run some 3rd party software but if you're actually building something you need to support it's important to have more control over your environment/libraries than the system-level package manager provides. The author gets it right on the Ruby side but their lack of experience on the python side here is showing. Pip and virtualenv are definitely the way to go today. For tomorrow you should keep your eye on the packaging PEP and the Hitchhiker's guide to packaging:

http://guide.python-distribute.org/introduction.html#current...

http://tarekziade.wordpress.com/2010/02/10/pep-345-and-386-a...

It's confusing but improving quickly. I know it took me quite a while to figure out what the right way to do things in python was.

This is also where rails' conventions help. As good as people say the documentation for Django is, many searches pull up blog posts from 2006 which were right for their time but now are simply outdated. That being said, I think there has been a tremendous boost in Django activity in the past year or so. I feel like they are getting in front of the curve again.

[+] c4urself|14 years ago|reply
If you're starting with Django, use pip + virtualenv, it seems to be pretty standard within the community
[+] jinushaun|14 years ago|reply
I agree.

I recently started getting hot and heavy with Linux after moving my stuff to EC2. I thought package managers were the bee's knees until I realised that my production server and my development box (at home) we're running drastically different versions of the same program/library. This of course caused a whole bunch of incompatibility problems and headaches when it came to building other stuff.

If you care about versions and stability, it's just safer and more reliable to compile from source that you know that works. Package managers can sometimes be a crap shoot.

[+] code_duck|14 years ago|reply
Yes, my thoughts as well at that point. Last time I checked, Ubuntu was offering Django 0.96 - installing through the package manager is bad advice when it comes to installing Django.

Installing from tar.gz isn't at all complex or difficult, either. The article would have been much more helpful if the author knew more about Python and Django.

[+] yesimahuman|14 years ago|reply
I wonder if he actually got version 1.3!
[+] po|14 years ago|reply
Rails and Django are two web frameworks standing at the same place greeting people coming from opposite directions. They are vaguely familiar with what each other are doing, but for the most part are just trying to do what's best for their own users. They have way more in common than they have differences and I think each community could benefit from learning the other's workflow.

I think Rails is slightly more beginner friendly because of the conventions and magic but that becomes frustrating for more advanced developers. Rails is working on making themselves more customizable and Django is working on codifying standards. I'm pretty sure it's a meet-in-the-middle kind of thing.

[+] dgallagher|14 years ago|reply
Official Docs - best official project documentation I’ve read. It’s actually so good, that I never (well - almost never) bothered to look for anything else. All my questions were answered by the official documentation.

I have a different opinion. The Django docs are good, but not great. Here's how I see them right now:

    - Combination of overview, how-to, and API reference.
Instead, I'd like to see it split up like so:

    - Overview section.
    - How-To section.
    - API reference.
The overview section should cover general concepts. "This is what a View is, how it relates to URLConf, etc...".

The how-to section should show you how to do certain things. "Here's example code of how you can configure settings.py, how to handle an HTTPRequest in a view function, etc...".

The API reference, just a list of Django objects (showing inheritance), their attributes, functions, and parameters. Excellent example: http://api.rubyonrails.org/ . Currently some of this is documented, but some of it is only visible in source code.

Right now, everything in the Django docs is semi-bunched together. This made it really hard for me to initially learn the API; I'd imagine others' have similar issues. Since then I've gotten use to the docs, but it's still frustrating at times.

I do like Django very very much, but this is one of its pain points for me. It goes away with experience, but for new users it likely poses a bit of a challenge.

[+] jacobian|14 years ago|reply
I completely agree -- as the docs have grown in size [] the organization has gotten worse. Originally I designed the structure to be similar to what you laid out, but things have gotten a bit out of control lately.

We're workin' on it, though, so if you'd like to help out I'd really appreciate it!

[] The length has nearly doubled in the last two years.

[+] Murkin|14 years ago|reply
One major area that the author did not cover: Modules.

The idea of 'Gems' in Rails(ruby) are exceptionally well engineered. Many powerful tools can be added by simply including a Gem.

On the Django side I have found the situation to be much worse. Many 'Apps' are hard to integrate and often it is easier to rewrite simple things than trying to customize them.

This is what caused me to switch to Rails after a year with Django

[+] askedrelic|14 years ago|reply
This has been a frustration of mine as well.

In the Convention over Configuration mindset, there doesn't seem to be a "best" convention for Django apps. You can install a django package easily through pip, but then does it need urls added, middleware, or signals added in your settings.py? The amount and quality of integration docs provided depends from package to package.

[+] glenjamin|14 years ago|reply
I think there are advantages to each.

Rubygems combined with bundler is an excellent way to package up functionality, specifiy dependencies and have things play together nicely.

pip + virutalenv is similar, but not quite as good at this part - but python having module namespaces makes it far easier to write packages which you can be sure wont stomp all over each other.

[+] joshfinnie|14 years ago|reply
Unfortunately, this article sounds very much like he was just introduced to Django. Great write-up overall, but it felt like lip service to Django with the real meat of the article is the RoR stuff.
[+] redsymbol|14 years ago|reply
Does anyone know what the "<(" syntax does:

  bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
I couldn't find documentation (hard to search for as you might imagine). Testing it out, basically that line downloads and executes the bash script stored at https://rvm.beginrescueend.com/install/rvm . Would like to understand how it works; is it related to the $(command) expansion construct? Why not use "curl -s http://files.redsymbol.net/foo/foo.sh | bash"?
[+] kragen|14 years ago|reply
<() is a new way to do I/O redirection, by which I mean it was introduced by I think the Korn shell in the early 1990s, which explains why you haven't heard of it. Also it isn't implementable on all Unixes.

The way it works is that if you say

    foo <(bar) -o >(baz) <(quuz)
foo sees them as command-line arguments, which might look like

    foo /dev/fd/3 -o /dev/fd/4 /dev/fd/5
and if it is clever enough to treat them as filenames and open them, then it will get the stdout of bar, the stdin of baz, and the stdout of quux, respectively.

The way this works is that the shell opens pipes to the other command lines first, then generates filenames for them.

I did not know that you could use it with other I/O redirections such as <!

As a bonus, the <() syntax means you can pipe even to and from commands that don't read from stdin or stdout. They must not, however, depend on the ability to seek.

My most common use for this is nonlinear pipe flow, e.g.

    diff -u <(sort -u file1) <(sort -u file2)
Hope this helps!
[+] robbles|14 years ago|reply
I think the parentheses are just for grouping of the second command. The "<" means feed the stdout of the second command into the stdin of the first.

So what's happening here is the output of curl (a script) is being fed directly into a bash shell and executed. I think it's basically an awkward way of piping a command in reverse.

[+] frankwiles|14 years ago|reply
He's not harsh on either, but I found it strange that having a pluggable admin is ok for Rails, but pluggable migrations like South was a big gripe.
[+] c4urself|14 years ago|reply
Nice writeup. Thankfully doesn't have a clear bias like most of these type of comparisons! A powerful Django feature (the admin) is rebutted by citing plugins in Ruby; I think that the fact that it's part of Django really makes a difference, with the smallest Django test project you can enable the '/admin/' and use the models. Either way I agree with the conclusion: for webapps you really can't go wrong with either
[+] sabat|14 years ago|reply
The difference is philosophy. The RoR guys think of things like built-in admin interfaces as appropriate for plugins because not every app needs such a thing.

As a guy who happens to have a security background, I'd discourage admin interfaces built into the same app as the user app, especially when it's named /admin. Keep your admin functions in a separate and locked-down app if at all possible.

[+] kmfrk|14 years ago|reply
Rails's community advantage over Django looks like something that is not likely to go away in any foreseeable future. Although Sinatra is getting popular, Pythonistas are split between Django (or the AppEngine variant), (Jinja), Tornado, Flask, Jekyll, Pylons, and so on.

With Ruby, Rails oftentimes seems like the obvious framework, whereas the same can't be said for Python and Django.

Getting into Django has been a bit of a pain in the ass for me - at least for being unable to work on it organically with some fellow students or co-workers - but is there any reason to believe that getting a big Python framework community similar to Rails's is a plausible prospect?

[+] Pewpewarrows|14 years ago|reply
I don't know where you are getting the idea that Django's community is more than marginally smaller than Rails'. Google Trends, StackOverflow questions, number of GitHub projects, average followers/forks for popular Django/Rails extensions, number/popularity of significant sites built with each, and the number of stories I see pop-up on sites like HN for each framework are all relatively equivalent.

Django for AppEngine is barely a variant, it's just a different handler for the ORM to interact with the non-relational backend. Jinja's a template engine that you can plug-in on top of Django if you want (like if you wanted to use HAML instead of ERB). Plenty of Django devs choose Tornado for their COMET needs (I know of almost no one that uses it as their entire web stack). Flask and Bottle are nice micro-frameworks, but aren't well-suited at all for large sites unless you feel like doing a lot of extra work yourself. Jekyll isn't a Python project, it's Ruby's static site generator (but does have a Python port called Hyde). Pylons (now Pyramid) is the only significant contender to Django. Think of it as Sinatra's market-share compared to Rails.

So when you actually compare the two, Python has no more "framework fragmentation" than Ruby. To someone outside of the community just listing off frameworks that they found on Google, sure it might seem that way.

[+] kingkilr|14 years ago|reply
I see it as unlikely there'll be real consolidation, ironically for a language with a "one obvious way to do it" philosophy there many different opinions about how a framework would work. That said there is progress on consolidating some of the infrastructure, e.g. discussions on a creating a unified request objects for frameworks, a GSOC by Armin Ronacher (author of Jinja and Flask) under the Django banner to create a unified template compiler framework for both to share, and a work-in-progress PEP by Laurens Van Houtven about unifying some APIs that asynchronous frameworks have and bringing some useful base classes into the stdlib.
[+] lsemel|14 years ago|reply
As far as documentation, I've found Django's approach to work better for me. It seems to be the norm in the Python community to document well and comprehensively. Python is the only computer language I've seen where, according to the creators, "Strunk and White apply" (http://www.python.org/dev/peps/pep-0008/) . With Rails, the community approach toward documentation too often seems geared toward beginners. Many gems provide a "copy this, generate these files, and type that" tutorial or a screencast. I'm reminded of the code-generating wizards you'd see in Microsoft Visual Studio back in the day. Often there's no documentation beyond an initial tutorial. When I tried Rails last year I found myself spending the majority of my time Googling and sifting through blog posts of varying age and quality in an often futile attempt to find what I needed, whereas with Django the majority of my time is spent actually coding, and if I really can't find something in the documentation, Django's code is so readable it's often easy to open up the source and discover what it's doing.
[+] yumraj|14 years ago|reply
I recently came across the Play Framework for Java. Though I haven't started using it in a real project yet, it does seem very interesting and rails/django-like with very similar tools and workflow, though for Java.

So for folks who are trying to decide between Rails and Django, Or come from Java background, that is another framework to look at.

[+] mgkimsal|14 years ago|reply
Throw Grails in there too, except with more Groovy if you don't want just plain old Java.
[+] nzoschke|14 years ago|reply
To me, this choice comes down to what type of site I am building.

For an API: Sinatra. A CMS: Django. A sprawling web app: Rails.

Each frameworks was built to address a very specific set of problems.

[+] zeemonkee|14 years ago|reply
I've built many a "sprawling web app" quite successfully with Django.

Django and Rails have long since outgrown their original, in-house roots.

[+] mgkimsal|14 years ago|reply
Do you really think that's true, that each was built to solve a specific set of problems? Or do you think each team thinks of their tools as much more generic, and applicable to a wide range of problems? I'm not aware of too many frameworks that tout themselves as being built only for a narrow set of problem domains.
[+] d0m|14 years ago|reply
I could have bet 100$ that RoR would have been chosen simply by reading the first paragraph: "I've already used Ruby a few years ago but I'm new to Python". What else do you want?

On a side note, Django is far from being "minimalist"; http://flask.pocoo.org/ is minimalist, not django. I'll agree that Django is also less "Convention over Configuration" than Ruby.. for instance, it's a bit hard to chose where to put helper functinos in Django, whereas Rails put a helper file for you, etc.

[+] mmccomb|14 years ago|reply
I can't speak for Django but I've just begun learning Rails as my first web framework and its been a pleasure to use. It's DSL is incredibly expressive and offers great power with little effort. Aside from the expressiveness the TDD integration and conventional project structure are big wins too.
[+] chmike|14 years ago|reply
I've picked Django because it can be run with pypy (jit python) and makes it very fast. I prefer minimizing server costs.
[+] eliben|14 years ago|reply
This is interesting. Do you have profiling information about Rails vs. Django in general and Django on PyPy in particular? It would be very curious to look at it from a performance point of view.
[+] drpancake|14 years ago|reply
Really? I was under the impression that most Django apps spend the majority of their time waiting on database queries.
[+] tijs|14 years ago|reply
That would be awesome. Unfortunately it's quite hard to build your full app on pypy right now as it's hard to compile working database drivers and some other things you might want to use in a web project.

Check out Alex Gaynor's slides from DjangoCon for more info here: http://alexgaynor.net/2011/jun/07/djangocon-europe-2011-slid...

[+] abrenzel|14 years ago|reply
I've been working on a new site in Pyramid (the successor to Pylons), and I have to say so far it's been an impressive experience. They took a bit of a different philosophy than Django and Rails. In those 2, you can customize some things, but there are also default options, and particularly things like the ORM are built into the framework. Pyramid behaves more like an application widget where the pieces of a modern web app (ORM, security, templating, URL routing) can be fit into its slots.

I did enjoy the article's touching on Django. It looks like it has gotten less monolithic than in prior versions. As I recall several years ago, Django really was like the Rails of Python, with tons of default options but some difficulties in customization. It looks like they have moved away from that somewhat.

[+] maercsrats|14 years ago|reply
That's not true about rails. Neither the ORM, templating or URL routing are built in. People use Datamapper or ActiveRecord, ERB or HAML and routing is handled as rack endpoints.

Rails 3 is much easier to pull apart and put in pieces that you want. I believe this will be even easier with rails 3.1 introducing engines as a first class citizen.

[+] inovica|14 years ago|reply
Glad to hear that. I'm just about to start creating a site using Pyramid. I've spent a lot of time evaluating frameworks and this one just seems to fit with the way we like to work
[+] phugoid|14 years ago|reply
I'm looking forward to learning RoR, even more thanks to this article. But please don't get the impression that only Rails works well with jQuery and SASS. I've been using them with django as well. They're not baked into django, but nothing prevents you from using them effectively.
[+] tedsuo|14 years ago|reply
What about optimizing your app later? I've rolled out a number of rails apps, and I now feel that the rapid prototyping it provides is actually a form of technical debt. The execution speed and memory footprint mean you will have to scale harder, faster. I would like to remove framework components and middleware that I am not actually using, and transition cleanly from a rapid rollout to an optimized final product. But even in rails 3 I haven't seen good evidence that it's possible to do this, without being hackish. How do Django and other frameworks handle this?

Another way of saying it is I would like a framework that is "additive," where you start with a very lightweight core and then add components as you need them.

[+] brendoncrawford|14 years ago|reply
A word of caution... Django should always be installed from Pip. Avoid easy_install, apt and yum.