There can’t be only one.

Standard

I guess I’d better give up now. Guido announced at SciPy that Django is the “standard” web framework for Python. How’s that for a first two sentences of a blog post? Of course, only one of those two sentences is accurate.

According to the blog post I linked to above, Guido “hopes that Django and TurboGears will converge”. Sigh. Someone please tell me that Guido hasn’t fallen for the “Python is losing to Ruby because Ruby only has one web framework” argument. I’m pretty sure he hasn’t fallen for that argument, but just generally thinks it would be a good thing. Django and TurboGears converging would be very much akin to Python and Ruby converging (Tim O’Reilly would probably advocate that, since book sales indicate that Python is waning). They address similar problem spaces and even have some similar approaches in spots, but that’s really a superficial view of the whole.

Guido’s attraction to Django started with Django’s template engine. He compared it with Cheetah and said, toward the bottom:

I didn’t find too many other templating solutions. TurboGears uses Kid which XML-based, like Nevow, TAL etc. IMO these are no contenders because they are XML-based. As the Django folks mention, they use templates to generate non-HTML text files as well. And even if they could be used for this, the verbosity of the XML syntax and the inability to do a proper if-then-else in XML make template writing using XML a non-starter.

For generating HTML, I find Kid to be a natural fit. I think it’s more natural than TAL and Nevow because the programmer just puts standard Python expressions in the right places in their templates (rather than some other kind of expression). Being able to write good, clean XHTML and produce fine HTML for the browser is a great feature and a great way to work. In practice, because I don’t go overboard writing code in templates, so if-then-else has not been a real problem. And, Markup shows a fairly clean way to do it anyhow.

And, certainly, generating non-HTML text files with Kid is suboptimal. First of all, I’d say again that this is not actually a big problem in practice. Seriously. It’s just not something that comes up much on the mailing list. Besides, TurboGears makes it trivial to use one of many other template languages (including Django’s) for generating non-HTML formats. In fact, you can even do it in one method:

@expose("myproj.templates.showstuff")
@expose("cheetah:myproj.templates.textstuff", accept_format="text/plain")
def index(self):
    return dict(foo="5")

When you hit that controller method, by default you’ll get that dictionary plugged into the Kid template to produce HTML. If your browser sends an “Accept: text/plain”, TG will have Cheetah use the same code to generate a plain text view. Nice, huh?

TurboGears has a collection of APIs and idioms that I think make it great fun to work with, and I know others agree with me. Django has its own collection of features that others like working with. That’s fine by me, and it’s not likely to change any time soon.

With TurboGears, I definitely do not suffer from Not Invented Here. In Django’s defense, at the time they started they simply didn’t have the options available that I did when I started TurboGears. But, the Python community continues to evolve, innovate and produce incredible products. TG will benefit greatly from these projects, but it’s unclear that Django would follow suit.

Mike Bayer’s SQLAlchemy, simply put, kicks the butt of Django’s ORM (and that of Rails, as well). SQLAlchemy is already a solid second-class citizen in TurboGears, and will be a first-class citizen soon enough. Christopher Lenz saw the good in Kid and thought he could build a better Kid with Markup. Though it’s a young project, it looks great and has impressive results. Julian Krause liked CherryPy’s quick-and-easy URL traversal, but wanted to break it down to a WSGI core so he created RhubarbTart. Meanwhile, Robert Brewer has completely retooled CherryPy’s easy “filters” feature for CherryPy 3.0. And, for those who like their URL traversal in separate files with regexes, there’s always Ben Bangert’s Routes.

All of the things that I mentioned in that paragraph are not vaporware. With the exception of RhubarbTart, these are things that you can use with TurboGears now and that will likely be included directly with a future TG release. TG has had code contributions from quite a few people, but these things are all steps forward that have occurred completely outside of TurboGears but remain a natural fit for TG.

At EuroPython, during the Web Framework Shootout, we (Simon Willison, Phillip von Weitershausen and I) were taking questions from the audience and someone asked if we thought that TurboGears and Django would merge. My response now is the same as it was then: not very likely. Both projects have their own ideas and approaches and trying to force fit them just wouldn’t work.

Today’s TurboGears 0.9a9 release will likely be the last 0.9 alpha before 1.0 beta 1 comes out. Though many TurboGears users have been running the 0.9/1.0 code for some time, I’m looking forward to finally unveiling it more here, on TurboGears.org and in “Rapid Web Applications with TurboGears”. My thanks, as always, goes to the many TurboGears developers that make the project possible.