[Headdesk] In Django, Querysets are Lazy!

Posted by Elf Sternberg as django, python, web development

As I’ve been working on a project at Indieflix, I’ve been evaluating other people’s code, including drop-ins, and for the past couple of days a pattern has emerged that, at first, bugged the hell out of me. Django has these lovely things called context processors– they allow you to attach specific elements of code to the request context before the router and page managers are invoked; the idea is that there are global needs you can attach to the context in which your request will ultimately be processed, and this context can be grown, organically, from prior contexts.

Nifty.  I kept noticing, however, an odd trend: programmers attaching potentially large querysets to the context.  Take, for example, the bookmarks app: it has a context processor that connects a user’s bookmarks to the context, so when time comes to process the request if the programmer wants the list of the user’s bookmarks, there it is.

It took me three days to realize that this is not wasteful.  It says so right there in the goddamn manual: QuerySets are lazy — the act of creating a QuerySet doesn’t involve any database activity. So building up the queryset doesn’t trigger a query until you actually need the first item of the queryset.  It just sits there, a placeholder for the request, until you invoke it in, say, a template.  Which means that you can attach all manner of readers to your contexts, and they won’t do a database hit or other I/O until you drop a for loop into a template somewhere. I’ve been avoiding this technique for no good reason.

This also means that pure “display this list and provide links to controlling pages, but provide no controls of your own” pages are pure templates that can be wrapped in generic views.

Ah!  And this is why I didn’t get why generic views were such a big deal.  Information is often so context sensitive so how could a generic view possibly be useful?  The examples in the book are all tied to modifying the local context in urls.py, but that’s not really where the action is.  The action is in the context processors, which are building that context.

I feel like Yoda’s about to walk in and say, “Good, but much to learn you still have, padawan.”

Comment Form

Subscribe to Feed



July 2010
« Jun   Aug »