

Django 1.3 vs Rails 3: A not so final showdown - bozhidar
http://batsov.com/Ruby/Rails/Python/Django/2011/06/19/django-vs-rails.html

======
Spyro7
"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
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.

~~~
sigzero
Like P3 being the only actively developed branch. The P2 line will only get
bug fixes. Anyway, the Django core is looking at the effort for moving to P3
so it will happen. The move was slated to take at least 5 years and we are
only at the half-way point.

------
rbanffy
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.

~~~
c4urself
If you're starting with Django, use pip + virtualenv, it seems to be pretty
standard within the community

~~~
rbanffy
Which are more or less analogous to what he used for Rails.

------
po
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
_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
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.

~~~
dgallagher
Thanks for clarifying things jacobian. :) I'd love to help out in a limited
capacity (time constrained currently, unfortunately).

In the past I've submitted tickets via the Django ticketing system indicating
errors/clarification/what-not for the docs, but almost every ticket got
flagged as spam and didn't get submitted. I kinda gave up after that point.
Any suggestions on how to get tickets submitted?

Oh, and one tiny feature request to the ticketing system: password reset. :)

~~~
jacobian
Sorry about the spam filter. We get a shitton of spam (I think we're the
largest Trac instance anywhere) and it makes the spam filter rather paranoid.
If you're signed in it shouldn't get triggered.

Password reset is here:
<https://www.djangoproject.com/accounts/password/reset/>

~~~
dgallagher
Ah cool, thanks so much!

I'm not sure how customizable Trac is, but one idea would be to implement
reCAPTCHA for anything marked as spam (assuming robots are causing spam issues
and not users). If it gets solved, it's probably a human entering something on
the other end.

This is a Python 2 reCAPTCHA module I forked/updated:
<https://github.com/dave-gallagher/recaptcha-client-1.0.6-ssl>

~~~
jacobian
We've had that implemented since... I dunno, about six months ago maybe?
(screenshot: <https://skitch.com/jacobian/fgjmc/django>). Not sure why you
didn't see it. I wouldn't be surprised if Trac somehow didn't show it to you;
it's a bit of a mystery to me some times.

------
Murkin
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_

~~~
glenjamin
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.

~~~
pacemkr
I'm dipping into both Rails and a Python project right now (non-Django), both
for the first time, and had difficulty "listing required packages to go along
the source" in Python.

In Rails/Ruby I can use Bundler:

    
    
      git clone
      bundle install
      [do development]
    

I'd like to do the same for a python project:

    
    
      git clone
      _something_ install_my_dependencies
      [do development]
    

I looked into pip, but it seems I have to package my src into a Python module
and install that. setup.py doesn't make sense for my project since it's not a
module meant for redistribution. I intend to use py2exe. Basically I just need
a way to install dependencies for development.

    
    
      foreach thing in file
        pip install thing
    

is the best that I can come up with. This is admittedly not terrible, but I
feel like there is a better way and I just don't know about it.

~~~
chrismsnz
There is a better way! A virtualenv combined with pip and a project
requirements[1] file is the best way to handle this.

It even supports SVN/SSH checkouts and .egg distributed packages.

[1] [http://www.pip-installer.org/en/latest/requirement-
format.ht...](http://www.pip-installer.org/en/latest/requirement-format.html)

~~~
pacemkr
Can I use pip to just install the dependencies without packaging my project as
a module? I understand that pip installs "my module" to site packages or a
directory under virtualenv. This is not what I need. I don't have a "my
module" to install. I just need to make sure that the dependencies are
installed on the machine/virtualenv that I'm using for development.

I studied the requirement file documentation and I couldn't find a solution.
It seems that to take advantage of this feature in pip I have to write a
setup.py, and as I've mentioned that really doesn't make sense for my type of
project. Or am I misunderstanding something?

~~~
X-Istence

      pip freeze > requirements.txt
      pip install -f requirements.txt
    

Now whenever you go to develop, pip install -f requirements.txt, when you
update dependent packages, pip freeze.

You are by no means required to make your source code a module or anything
like that. If you use the above with a virtualenv you can isolate different
models for different projects and have them frozen at different versions. You
are also able to modify requirements.txt to include version specific
information. packagename==3.4.0 now locks packagename to 3.4.0 when pip goes
to install it.

I'm assuming your git directory looks like this:

    
    
      $DIR
      \
      | - requirements.txt
      | - fileone.py
      | - filetwo.py
      | - folder
         \ 
          | - __init__.py
          | - filethree.py
    

I have several projects set up exactly like that, especially since they will
never have to be distributed using a .egg or anything else.

~~~
pacemkr
Minor correction, it's dash r:

    
    
      pip install -r requirements.txt

~~~
X-Istence
This is indeed correct, I must have fat fingered that. Sorry.

------
joshfinnie
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
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
<() 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!

~~~
redsymbol
You bet it helps. Thanks for the great explanation!

------
frankwiles
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
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
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.

~~~
jonknee
At least for Django, there's no reason your built-in admin has to be on the
same site (or /admin). You can just create a new project, add the same apps of
your main in addition to the admin app and hook it up to the URL of your
choice along with whatever authentication you want (even limit to internal
IPs).

------
kmfrk
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
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.

~~~
kmfrk
What does it take to be "outside the community" in your opinion?

~~~
X-Istence
I would say his comment stems from the apparent lack of knowledge regarding
the different frameworks that are available Python and the lumping in of a
Ruby project with Python projects.

From an outside perspective it looks like you are skimming the service and do
not yet have a firm grasp as to the two communities and what they have
provided. This is okay, it is something you can alleviate by simply learning
more about the two communities, and hopefully in the future you will be able
to provide your opinion on the state of frameworks based on correct
information/facts.

------
lsemel
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
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
Throw Grails in there too, except with more Groovy if you don't want just
plain old Java.

------
nzoschke
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
I've built many a "sprawling web app" quite successfully with Django.

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

~~~
nzoschke
Me too. But I find Rails a lot more helpful, especially when your site turns
into a mashup of web with forms, Ajax and a bit of REST. Django doesn't have
opinions of much outside a standard HTTP request/response.

~~~
zeemonkee
Which is actually a good thing, provided you know what you are doing.

------
d0m
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.

~~~
hello_moto
Flask looks exactly like JAX-RS that ships with Java EE 6:

<http://download.oracle.com/javaee/6/tutorial/doc/gilik.html>

Unfortunately JAX-RS has not been integrated with JSP or any templating
languages yet.

------
mmccomb
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
I've picked Django because it can be run with pypy (jit python) and makes it
very fast. I prefer minimizing server costs.

~~~
eliben
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.

~~~
chmike
My opinion is base on the following benchmarks :
<http://attractivechaos.github.com/plb/>. This is obviously not a typical web
application, but it gives a good hint on the performance issue.

Those interested in a C++ web app framework might consider wt (webtoolkit). It
has a built in http/https web server and is thus plug&play for average
applications. It is worth a look at.

------
abrenzel
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
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.

------
phugoid
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
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
A word of caution... Django should always be installed from Pip. Avoid
easy_install, apt and yum.

------
yesimahuman
I think seeing the huge project structure after initializing a Rails app vs. a
Django app is what keeps me away from Rails. I prefer a minimal starting base
that lets me immediately make decisions about my app. I do need to give rails
another chance though.

~~~
wonnage
If anything you should prefer Rails in this case. Django generates fewer
files, but what if you want to customize the automatic stuff? I'm talking
about the admin templates, etc. You end up needing to copy the files over
anyway.

I'd say the two give you the same amount of framework code to start with.
Rails just happens to let you see and fiddle with it right off the bat.

In any case, when I start a new project I don't want to worry about creating a
bunch of files and remembering where to put them and doing all this setup. I
just need some sane defaults, so that I can start making actual project-
related decisions instead of fooling around with "how do I want to arrange my
files this time?"

~~~
tomkr
It is possible to override admin templates while maintaining inheritance from
the baked-in templates. You can check here:
[https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#ove...](https://docs.djangoproject.com/en/1.3/ref/contrib/admin/#overriding-
admin-templates). Anyway it is better to look at the admin not as part of the
framework, but a bonus app you get to get started with modifying data.

------
pajju
I think he got it totally wrong with his unscientific estimation of rails and
django with google trends. What has google trends to say here? Dislike.

------
Yxven
I switched to django from rails 2 years ago because I grew tired of getting
burned by black magic. Back then, rails had the reputation of being amazing at
building specific types of web applications but going outside that box only
resulted in pain. I haven't heard that recently. Has rails gotten better in
that regard? I know they've gone through at least 2 major revisions since I
knew how to use it.

