Armin Ronacher

Opinionated Frameworks

written by Armin Ronacher, on Tuesday, January 6, 2009 0:32.

Once again my post about Jinja and the Django template engine appeared on reddit. The second time in the last two weeks, probably because my feeds changed and planets re-displayed it.

I originally wrote the post a few months ago to promote Jinja a bit. I was and still am very happy with Jinja2 and wanted to write some lines about what I like about it and how it works. And I also was hoping that the Django guys have a look at it and copy some features of it. Mainly because every once in a while I contribute code to a Django powered project or have my fingers in some way in such a project's code. And every time I'm kinda puzzled how simple some really complex tasks in Django are.

So what has changed in Django's templates the last four months? Not that much. The only changes in the Django template engine was the addition of {% empty %} blocks in {% for %} loops (which does exactly what Jinja's {% else %} does for loops) and some bug fixing. Is that a problem? I don't know, but probably not.

Django's templates are still slow and limited as they were, but it's not causing problems so that users have to switch. Every once in a while I notice that people switch to Jinja from Django templates because of performance of the limitations, but very often they throw away half the framework because they discover that Python has more to offer than just Django. And with that in mind I guess the Django guys are doing the right thing.

Django is designed for content driven websites not so much for independently deployed applications (like trac, WordPress, MediaWiki and others). So not so much for applications and also not so much for stuff where you need crazy database queries that are not possible with Django. The template engine is designed for simple HTML generation and that's it. If you want more, you often want something different than Django anyways.

I know many successful projects that are running Django without problems and it works out for them, because their requirements match (nearly) exactly what the framework was developed for. And I know many that adopted Django because of the fuzz but what they actually want to do does not fit into the Django style of development.

In many ways Django reminds me a bit of unpacking cool stuff. You download it and are instantly blown away how cool it is. Database just works, templating is awesome, URL routing gives you these incredible neat looking URLs and much more. It's so cool that many are trying to suddenly do everything with it. And that's kinda where the problem lays. You are forcing Django to do things it's not designed for.

I think what is missing is a website that explains the advantages and disadvantages of the particular solutions and what projects work best with what solution. There are Pylons, Werkzeug, Paste, Repoze and a lot more frameworks and utility libraries that focus on different kinds of web applications. And that does not only apply to full blown frameworks or WSGI utilities, but also template engines, database libraries and even databases themselves. It would prevent a lot of frustration if people could find the framework or toolchain of choice before they start developing their project.

But such a page would have to be designed by someone unbiased. And neither me, nor anyone else who develops on/for a Python powered framework should create such a comparison page. But I would encourage everybody with experiences in multiple frameworks to write down their experiences with different Python frameworks, template engines, database adapters and combinations thereof.

Update: Fixed misleading sentence. Swapped complex and simple.

Comments

  1. Django is designed for content driven websites you don't deploy.

    That's uncalled for. You're welcome to disagree with our philosophy, but this is just 100% bullshit and you know it.

    If you're serious about getting people to take a look at your suggestions, insulting them is a pretty terrible way to start.

    —  Jacob Kaplan-Moss on Tuesday, January 6, 2009 3:23 #

  2. I think the people involved with the frameworks are actually entirely capable of producing a comparison document, if they wanted to. It'd have to be something wiki-like where the ultimate product was one of consensus. But it would require considerable effort on many people's part, and that hasn't come together.

    —  Ian Bicking on Tuesday, January 6, 2009 4:18 #

  3. Django is just good enough for me!

    —  omtv on Tuesday, January 6, 2009 4:22 #

  4. This just reminds me of "Fastest templating engine ever. Period."

    Hey. I'd forgotten that Armin had commented on that article!

    —  huxley on Tuesday, January 6, 2009 4:37 #

  5. The template engine is designed for simple html generation and that's it. If you want more, you often want something different than Django anyways.

    But you can swap out the template engine. You can optimize & hand-tweak your SQL if need be. Django does things right by being modular and by not forcing things on you.

    Use the parts of the framework that work best for your application.

    —  Matt Silverlock on Tuesday, January 6, 2009 4:39 #

  6. I didn't read "Django is designed for content driven websites you don't deploy" as terribly offensive. But maybe that's just 'cause I was confused by it. My interpretation was that someone other than the developer deploys the app (sysadmin?), but I'm sure that's not more true for Django versus other frameworks. My other interpretation was that Django apps don't need to be deployed, but that doesn't make sense.

    ?

    —  Wyatt Baldwin on Tuesday, January 6, 2009 4:57 #

  7. Can you provide an example of something Django simply doesn't let you do?

    —  Alex Gaynor on Tuesday, January 6, 2009 5:28 #

  8. "And every time I'm kinda puzzled how complex some really simple tasks in Django are."

    Do you have an example of such task?

    "So what has changed in Django's templates the last four months? Not that much."

    Django does a lot more than templates. It is understandable for the template engine to advance slower than a project that does only templates.

    An objective framework comparison would be great. And I believe that those involved in building a framework can be objective about what they're building. The collaborative aproach Ian proposes sounds great. All we need is someone to build a site for comparing the different aspects.

    —  Nicolas Lara on Tuesday, January 6, 2009 6:02 #

  9. Can it dispatch an incoming request to an subapp in your app based on the domain (not subdomain).

    Ie. a request to apple.com and orange.com gets sent to django.apps.fruit whereas cucumber.com and carrot.com gets sent to django.apps.veg

    All this being dynamic of course, so apple.com might point to something else tommorow.

    —  Marcus Brody on Tuesday, January 6, 2009 6:13 #

  10. Over at YTM we run a complex db model with a very optimized javascript style web application in front of it. Django works wonders for the task.

    Django's ORM is better than all of the mainstream web frameworks (Rails, Symfony) out there. We need to use sql alchemy though, which is perfectly possible to use with Django.

    A full integration between sqlAlchemy and Django would be really nice though. Django ORM already blows away the competition, but improvements are always welcome :)

    —  Thierry Schellenbach on Tuesday, January 6, 2009 7:43 #

  11. I actually thought your article about the differences between Jinja and Django templates was interesting, but this is just silly.

    As long as your changes can't be used without having Python code in the templates, they are probably not going to be merged into Django.

    —  Mikkel Høgh on Tuesday, January 6, 2009 9:52 #

  12. wow, wow, wow. That was quick.

    Django is designed for content driven websites you don't deploy.

    I miswrote that sentence. I meant it as "application you don't deploy on different machines". Think trac, WordPress, MediaWiki etc. Django is not suited for that as it requires your app to be on URL root, take the interpreter hostage etc.

    @8: Grml. I meant it the other way round :-/ Fixed it.

    @11: Jinja does not allow Python code in templates.

    —  Armin Ronacher on Tuesday, January 6, 2009 10:12 #

  13. Armin: That is still not true, Django can be deployed at any point in the url, it does not need to be at "/".

    —  Alex Gaynor on Tuesday, January 6, 2009 11:16 #

  14. @13: Then that must have been changed. Last time I tried the URL generation did not respect submounts.

    And yes, it surely is somehow possible. But compared to alternative solutions it's complicated and not reliable. The stuff I did with Zine would be nearly impossible on Django and make things more complicated than they have to be. So why chose Django for such a project in the first place?

    —  Armin Ronacher on Tuesday, January 6, 2009 11:48 #

  15. I miswrote that sentence. I meant it as "application you don't deploy on different machines". Think trac, WordPress, MediaWiki etc. Django is not suited for that as it requires your app to be on URL root, take the interpreter hostage etc.

    But, see, that's not true, either. See Review Board, Satchmo, Pinax, etc.

    Look, Armin: I know you're incredibly smart -- smarter than me, at least. There's some simply beautiful stuff in Zine (I spent a few hours over the holidays reading through it). So why can't you simply tell us about what's neat about Zine (or whathaveyou) without needing to trash on Django? Unless you're deliberately trying to stir up controversy from the Reddit/HN croud, everyone's going to be better served with a technical explaination of Zine than half-researched handwaving about how Django makes things "impossible."

    You don't like Django. We get it. That's fine: reasonable people can disagree. But that doesn't give you license to spread FUD.

    —  Jacob Kaplan-Moss on Tuesday, January 6, 2009 13:47 #

  16. I miswrote that sentence. I meant it as "application you don't deploy on different machines".

    If I understood you correctly, you mean deploy like a PHP application. Copy a bunch of files and they work. Most of your examples are also PHP.

    As you are aware, Python web apps fundamentally work differently from this. WSGI standard is one of the reasons. But it doesn't really mean that you cannot deploy it on multiple machines does it?

    Django apps are well-known for their reusability and is considered one of its strengths. The URLs can be designed any way you like. They are just regular expressions!

    I can imagine more 'solutions' which one can unpack and use like Ellington which can be built on top of Django.

    —  Arun on Tuesday, January 6, 2009 14:04 #

  17. @16: No. I just mean like an application, not like a website you have full control over. Take Zine or trac as an example. These applications have strong opinions on how dispatching has to work, how plugins hook into the system, how configuration works, how the API has to look like, they try to be deployable in a very flexible way etc.

    Zine for example is configured by creating a folder, copy/pasting a file from /usr/share/zine into that folder, creating an apache config to point to that folder, going to yourserver/blog and following the web setup. That requires a different kind of bootstrapping you can't have with django and you usually don't need.

    Some people suggested I should write up the things in Zine that would not work out in Django without hacks, and I'll give that a try. That should explain my and some other people's motivation a bit better.

    —  Armin Ronacher on Tuesday, January 6, 2009 14:32 #

  18. OK, on re-reading of my comments, I'm overreacting here. Armin, I'm sorry. I get peeved to hear that reusable, distributable Django apps aren't possible, but really that means I should write some damn documentation instead of nasty blog comments. Again, sorry.

    So, anyway: let's get back to this:

    I think what is missing is a website that explains the advantages and disadvantages of the particular solutions and what projects work best with what solution. [...] It would prevent a lot of frustration if people could find the framework or toolchain of choice before they start developing their project.

    I couldn't agree more. Shall we try to start one on the Python wiki?

    —  Jacob Kaplan-Moss on Tuesday, January 6, 2009 14:39 #

  19. @18: That sounds like a wonderful idea and ian bicking seems to be interested as well. Alternatively the wsgi.org wiki could be used, someone sat down and designed a nice theme for it, whoever it was :)

    —  Armin Ronacher on Tuesday, January 6, 2009 14:43 #

  20. @Jacob

    I get the impression that Armin isn't talking about "apps" in the Django sense of the word, but rather an app as a whole Django site.

    It is more challenging to deploy a django site to "example.org/something/" than to deploy it to just "example.org".

    —  Andrew Ingram on Tuesday, January 6, 2009 14:53 #

  21. @jacob : This is exactly why I love django and its community in general : the positive attitude Congratulation for you Mea Culpa

    —  yml on Tuesday, January 6, 2009 15:46 #

  22. I think most of this comes down to conceptual differences. In the talk that I've given a couple times about developing reusable apps with Django, I pick on Rails for its monolithic idea of the "application", which makes it hard to answer an important question: if I have some feature that's necessary for my site to work, but not logically the focus of my "application", where do I put the code for it?

    The Rails answer (and the answer of a lot of frameworks and of a number of the applications you mention) is to have extension hooks and plugin APIs and other things of that sort (including, more recently, Rack middlewares), so that additional code can be injected into the "main" application processing flow. In WSGI (and, these days, Rack) a lot of this can be done with middleware, which is just another API for that purpose, or applications can expose their own special-purpose APIs.

    The Django answer is to write another application, because Django's idea of "application" is not Rails' idea of "application" or most of the other Python frameworks' idea of "application". And so Django adds another conceptual layer: that of multiple applications (in the Django sense of the term) working together under a larger logical unit (often called the "project", though I have some issues with that).

    This means that instead of a WSGI server with different "applications" (in the WSGI sense of the term) hanging off URLs which act like mount points, you end up with a Django "project" (which, remember, can quite happily run as a WSGI application) internally delegating to its constituent "applications" (in the Django sense of the term).

    Django "applications" are a bit more promiscuous with each other than, say, the traditional WSGI conception of "application". Django applications in the same project frequently call import each other's bits, call into each other's code, etc., while the traditional WSGI view is that the "application" is basically a black box: requests go in, responses come out, and if you want to change behavior you add middlewares (more request/response black boxes) to the chain or use a plugin/extension API built in to one of the applications.

    For what I do, the Django approach is quite a lot more useful since it allows me to quickly compose functionality to get what I need (and the way Django is architected ends up having more to do with supporting this approach than with any desire to be "opinionated" or cut off developer options). For what you do, obviously not so much. But they're both valid approaches, even though they're different.

    I keep trying to write a more thorough explanation of this (one attempt was here: www.b-list.org/weblog/2008/feb/11/integrity/), but I either never finish it or Yet Another Frameworks Flamewar flares up and drags everything off-topic.

    —  James Bennett on Tuesday, January 6, 2009 16:01 #

  23. I have yet to find something that I can't do in Django. Not only that, but I can do things in Django 50 to 100 times faster than any other framework I've ever used

    I feel it's offers a great balance in what it will and won't allow you to do on the template layer, and it's modular enough to let you build an economy of scale very quickly. The admin alone was enough to make me switch all of my freelance work over to Django, which has given me back weeks, if not months, of my life.

    Having been a professional web developer for more than a decade, Django has finally brought back the fun back in development.

    —  Brandon Taylor on Tuesday, January 6, 2009 16:41 #

  24. One thing that might help a bit to combat the Django-vs-everything else situation that leads to feeling a need to contrast Django vs. some adhoc solution based on WSGI components and other libraries would be to decouple some of the awesome completely general-purpose Django functionality (e.g. django.utils.encoding and django.utils.http, etc, and a lot of other stuff in utils, like django.utils.functional wrappers for Python 2.4 for being able to pickle decorated functions, etc) from "Django the web framework". I cut and paste this stuff all the time, it's great.

    I have the sense that Jacon and Adrian and James are not fans of the current crop of Python packaging dependency solutions. I don't quite know how to fix it, though.

    —  Chris McDonoug on Tuesday, January 6, 2009 17:12 #

  25. Um... hmmm... why do think its hard to deploy django under sub urls?

    This is how the pycon website has been developed since django 0.91!! the us.pycon.org website is currently running PHP, zope, web2py, and 5 django instances under different sub urls, 1 using mod_python, 2 under fastcgi+flup, and 2 under wsgi.

    Didn't have any problems. What problems are other people having?

    —  Doug Napoleone on Tuesday, January 6, 2009 20:04 #

  26. Django works best for content-driven websites. That's what it was developed for.

    Consider a typical website with some pages, a blog and a photo gallery—three Django apps. This is what Django is good at.

    On the other hand, for applications (as opposed to websites) like Gmail, Facebook, etc., I wouldn't use Django.

    —  Adeel on Wednesday, January 7, 2009 4:14 #

  27. FWIW, I write business intranet applications all the time. Some with really bizarre backends like a Cobol C/ISAM<->SQL gateways, Beagle/Tracker, etc. For example, generic report generators based upon accounting and inventory data, simple enough for end users to design and run their own reports. I've just finishing up a multi-company inventory maintenance system that interfaces with an accounting/point of sale system. All in Django. I really can't imagine using anything else. (And yes, I've done this kind of work in Rails and TurboGears, too.)

    Django templates have required my learning to think in terms of the "one logical way to do it", much as with Python itself. But I'm quite satisfied with their capabilities, and their philosophy.

    —  Steve Bergman on Wednesday, January 7, 2009 21:28 #

  28. I think it's time to start UnusualDjangoSites.com to collect all NOT CMS Django sites around the world.

    You will be surprised I believe..

    —  Nick on Friday, January 9, 2009 1:48 #

  29. Frankly, I do not know there will be anyone who really knows more than two frameworks (if only) to the degree they can criticize them. I think most people hardly know one framework well while the rest know their one well. There are some who may know two frameworks well but they have usually better things to do.

    —  Jiri Barton on Friday, January 9, 2009 13:21 #

  30. @Jacob I would seriously lay off accusing people of FUD all the time. @James Bennet "Yet Another Frameworks Flamewar flares up and drags everything off-topic.". You mean that you start with passive aggressive attacks on your attack blog?

    Seriously, Jacob and James, you guys need to quit attacking people every time someone disagrees with Django. Your both acting like bullies and should be ashamed!

    —  Noah Gift on Monday, January 12, 2009 9:25 #

  31. @Noah: Please try to keep your comments constructive. As the blog post was originally written, Jacob's response was quite understandable. (And please see comment #21.) And James' comment was one of the most constructive in this thread. I see no reason for you to attack them.

    —  Steve Bergman on Wednesday, January 14, 2009 3:26 #

  32. @Steve,

    There is a long history of Jacob Kaplan-Moss and James Bennett acting like childish bullies when Django is mentioned in a possibly negative light. James Bennett in particular is a lightening rod for making vehement personal attacks on people on his blog.

    While I do enjoy using Django software, I am very disappointed that there is a "Lord of the Flies" type leadership strategy, where a different opinion from James or Jacob turns into "lets kill Piggy".

    —  Noah Gift on Sunday, January 18, 2009 1:12 #

  33. There was a framework comparison kept by Paul Boddie, although it's out of date now. www.boddie.org.uk/python/web_frameworks.html

    The issue is not FUD or insults. It's whether Armin's claims are correct. Namely, that Django templates are unnecessarily complex, and that Django is not suited for non-CMS sites. Both of these are legitimate arguments (whether or not they're correct), and deserve to be argued at face value. It's not an insult to raise these. If his conclusion is overreaching, just say so.

    @Jacob: take a hint from Bill Gates. When your product is famous, some people will say bad things about it. So get over it.

    @Noah: I don't know what James may have written elsewhere, but this comment is reasonable and not bullying. If Django has a different concept of application, that's worth saying. He wrote, "For what I do ... Django is more useful ... because it allows me to". That's called owning your opinions. As opposed to, "Django is more useful (for everybody, say I, God)", which is more likely to be an overstatement.

    Finally, this is Armin's blog and the title says "Opinionated Frameworks", so it's not there was no warning there'd be (possibly biased) opinions here.

    —  Mike Orr on Monday, January 19, 2009 20:01 #

  34. I thought this review on Amazon about a Rails book was particularly fitting for this discussion:

    www.amazon.com/review/R182FW0JFXX0OX/ref=cm_cr_rdp_perm

    "Nobody dares point out any of the framework's flaws for fear of angering the infallible DHH and being ostracized from the internet clique his ego has built up over the years, so instead of practical information we have a giant sludgy pool of homogenized evangelism to wade through as we figure the ugly bits out for ourselves. "

    For Django I say ditto!!!! Python people need to get some balls, and say when something is good, bad, or ugly. If it makes Django mad...tough...James and Jacob are little girly men anyway, what are they going to do...beat you up? Unlikely, instead the worst they can do is cus you out on a blog either anonymously or publicly, as they wouldn't dare insult you like that in person.

    This is another great review, btw, on Jame's book:

    www.amazon.com/review/R1SBYLO66CC6WY/ref=cm_cr_rdp_perm

    —  Noah Gift on Tuesday, January 20, 2009 8:06 #

  35. Didn't Google choose Django for its App Engine.

    —  MySchizoBuddy on Wednesday, February 18, 2009 23:55 #

  36. AppEngine is framework-less and runs any WSGI core that is not using a database.

    —  Armin Ronacher on Thursday, February 19, 2009 7:14 #

Leave a Reply