I thought it would be interesting to write down why I chose TurboGears over Django and Ruby on Rails as a sort of counterpoint Tabo's post here:
http://tabo.aurealsys.com/archives/2005/10/11/django-or-why-i-chose-it-over-turbogears-and-ruby-on-rails/ I'll throw this up on the web eventually, but I was thinking maybe some here could offer their own reasons for choosing TG. As a bit of background, I first started developing database backed websites in 1996 using Perl CGI scripts and Mini-SQL. I eventually moved on to mod_perl, using Mason and Template-toolkit. A couple of years ago I got into PHP, excited about a ubiquitous and fast replacement for CGI scripts. PHP is a fairly terrible programming language, but if you want to distribute web software it is great because everyone already has it on their web server. I co-authored a book on PHP and wrote countless lines of PHP but I often found myself working around PHP's limitations rather than writing useful code. (And lets face it, it is so much more fun to write code in Python than PHP) Then at the beginning of this year I decided it was time to move on. Time to learn something new. I decided to take a look at Java, Ruby and Python. I would not have guessed I would end up picking Python, but I fell in love with the clarity of the syntax and the lack of endless magical functionality*. Having decided on Python I was a little disappointed that it seemed very few people were using it for web development. The web frameworks that were available were really URL to function mappers with perhaps a template language thrown in. Nothing wrong with that, just far from a full web development stack. I ended up using a simple python server pages implementation for templates, wrote my own ORM for Postgres and used SCGI for the application server. And things were good. Sometimes I wished for a Rails-style development environment in Python and occasionally something similar would come along, but nothing that really provided a compelling reason to switch from my homegrown web-stack. Then I heard about Django - I checked it out, but they were just beginning to write the documentation and didn't have any videos (ooohhh shiny webcasts!). Shortly after that Kevin Dangoor launched TurboGears (and in a show of marketing shrewdness did the shiny webcast thing). I decided to take a good look at both to see if I could ditch my homegrown web stack for one and free up more of my time to write actual useful code. TurboGears was still very much getting off the ground and the Django guys were starting to get a lot of the docs complete so I decided to try out Django first (also Rob Curley's talk on IT conversations had piqued my interest). I spent about a week playing with Django and reading through much of the source code. I even submitted a couple patches. More recently I have spent a few days with TurboGears. I want to start with a bit of a disclaimer. Both projects are a large leap forward in Python web frameworks. Both are managed by very capable developers with strange last names (Django: Adrian Holovaty, TG: Kevin Dangoor). Both are worthy choices for your web framework. I'll break down this comparison into four parts: 1. ORM layer 2. URL mapping 3. Templating 4. Other Stuff ORM Layers TurboGears uses SQLObject and SQLObject is better. Django's ORM isn't terrible, but SQLObject gets more things right. Using strings for foreign key references between tables instead of the real class is a big one. It makes setting up complex relationships between tables possible. Some may prefer Django's syntax for doing selects over SQLObject's sqlbuilder, but I personally prefer the more pythonic sqlbuilder. (If you are blessed with only needing very simple models you may never notice the limitations of Django's ORM in which case this becomes a much closer comparison.) URL Mapping This one has to go to Django. The regexp-based url mapping makes it easy to have beautiful, clean URLs in your app and to map them to any arbitrary function. Things like: http://www.example.com/blog/my_slug_here/ You can do this sort of thing in TurboGears, it just isn't as easy. TurboGears uses CherryPy for a front end which really prefers options to be specified in get variables like http://www.example.com/blog?slug=my_slug_here Templating When it comes to templating, I think there are two camps. One, take the full power of a programming language and make it available in your templates. The other is to implement a templating language that barely does anything other than variable interpolation and then slowly add features to it until it becomes a programming language in it's own right. TurboGears has chosen the former and Django has chosen the latter. TurboGears uses Kid which lets you write templates in XHTML with little embedded python if statements and for loops. You can embed full python functions in a template if you want to, but they can't output anything directly and it isn't recommended. You do get the full power of python in your if clauses and for loops which means you can do any sort of arbitrary comparison that you need. Things like: <p py:if="system() == 'Linux'"> Good for you! </p> You can also define custom template functions and tags that act as reusable blocks of HTML and kid can translate your XHTML code to HTML 4.0 for you - it is really quite flexible. The Kid language spec is here: http://kid.lesscode.org/language.html Django uses their own template language which has a cool inheritance feature. You can define your own tags that hook into the template parser to add functionality. Django also implements a feature similar to Template-Toolkit's Stash that allows you to use dots for method calls, dictionary lookups, etc. So if you have foo['bar'].baz() You can call it from your template like: {{ foo.bar.baz }} Cool! They have some basic functions like an if statement, but it can only check if a variable is true, no comparisons. So you can do {% if foo %} Wow foo is true. {% endif %} But you can't do {% if foo > 5 %} This doesn't work {% endif %} If you want to do a comparison, you have to use ifequal {% ifequal foo bar %} wow foo is equal to bar {% endifequal %} They also have ifnotequal and I suppose it is a matter of time before someone implements ifgreaterthan, iflessthan and maybe even ifgreaterthanorequalto, but this just seems silly to me. If you are a big template minimalist you may prefer Django's approach, but as soon as you want to do something slightly advanced like see if one variable is greater than another your head is going to explode. You could use another template system with Django, but a lot of the things that make Django so nice like generic views and the built in admin depend on the default template system. Other Stuff TurboGears is a bit newer. Django has a bit more thorough documentation at the moment. TurboGears has built-in support for Ajax - you can use the same controller methods for generating HTML and dumping out JSON. Django has some features that are still in development on the TurboGears side, notably a web interface to your model objects and full form handling. But these things are not so hard to develop. The areas where Django is lacking (ORM and templating) will not be as easy to fix. It is true that TurboGears is made up of separate projects but I don't think you can really "feel the glue" - maybe you can still smell it, but it appears to be drying very quickly. (*) When I was writing lots of Perl code I always had this vision of Larry Wall and crew talking about Perl features like: "We must have a magical loop variable" - "Yes, but what shall we call it?" - "Why $_ of course! Unless it is an array, in which case it is @_!" - "Perfect!" I should mention that I loved Perl and still have a certain fondness for it and will leave all this Python nonsense behind the second Perl 6 is done (just kidding ... we'll all be one big happy family on the Parrot VM, right?!) Sean Cazzell

