I have been doing a bit of work in Python, lately. As I am generally a "web guy," this means spending time with Django. This post is admittedly heavily bias and probably includes mistakes and omissions. The standard disclaimer applies. However, I am hoping that someone out there on the tubes will be able to help me understand these minor annoyances and point me in the direction of a better way.
Django has a usable ORM. For the majority of uses, it Just Works(TM). So there are a few more underscores than I would prefer to look at (my "_" key is looking haggard) and the related object API is a bit... odd. Whatever. I can deal.
However, to quote Jerry Seinfeld, what is the deal with transactions? Why is the middleware seemingly the only elegant way to control transactions? Okay, so Django likes to tie these things to the request/response cycle. Most of the time, that is what I want. Most of the time. Please tell me there exists some decorator-based support for transactional methods in the Model, though. Please.
Most of the world calls this the Controller, in MVC parlance. Again, no big deal. They consist of methods that sit in between the Template (views, to the rest of us) and the Model. The rendering support arguably reads a bit oddly, but we all already know that I have a fetish for readability.
There must be a better way to handle error conditions in the Model. The typical action in Django seems to be to wrap each Model interaction with try/except clauses and hope you've caught everything. Yes, I know Python is predisposed to abusing exceptions, but this interface is crying out for something cleaner. Something saner. Something else.
I cannot for the life of me find a decent way to handle PUT/DELETE requests in views without
wallowing in here. I
strive for interfaces that at least pretend to be RESTful, but Django does not seem to care much for
that philosophy. A shame.
This is a personal soapbox. At both the language and framework level, testing should be clean, unobtrusive, flexible and fast. xUnit-style tests are fine and well, given adequate support for the framework's primitives. In the web world, this means managing database state between tests, loading up fixture data, executing faux web requests and testing integration points with caches and peers.
Yes, Django has a cursory
examination of
testing a web application. Ironically, doctest is lauded as feeling more "pythonic," but there seems
to be better support for testing each component of the stack using the unittest style. Moreover,
doctest begins feeling like a cruel joke when test coverage grows to anything more than example method
usage.
Django's documentation explicitly states that "most projects will end up using both." I hope this is an intermediate step, until someone builds a more elegant harness.
Django provides a script with each new project in the form of manage.py. It works as advertised and
creating custom commands is straightforward. I do miss some other
tools, but it gets the job done.
With its usurped motto of "batteries included," one would think log
output has received as much attention as command execution, though. import logging and other
boilerplate hoop-jumping is not the answer, here. When the application is running in development, at the
very least console output should include useful tidbits such as SQL statements executed by the ORM and
stack execution times (the template engine...). Also, the framework should provide an elegant way to
output custom messages. I hope I have completely missed some part of
this page. And yes, I know about
this.
UPDATE: There appears to be an effort to improve this situation for Django 1.2.
Deployment has been covered ad nauseum elsewhere, but suffice to say Python web application have a long way to go before they reach parity with others.
Django is certainly an acceptable framework in daily usage. Its rough edges are bound to be honed by the raging torrent of time and use. The emphasis on pluggable "apps" is a pattern I am happy with, the middleware infrastructure is well thought out and well executed, and most of the common use cases for a web framework (nee CMS?) are covered.
As I said in the introductory text, this post is composed of minor annoyances that make my life a little harder than it really ought to be. I hope to post followups to this little diatribe exploring solutions to each of these gripes. If you have a solution that puts a smile on your face, let me know via email or twitter.