We frequently write little functions that populate the Django context, and sometimes we want that context to be site-wide, and we want every page and every Ajax handler, basically everything that takes a request and spews a response, in our application to have access to that information. It might the user’s authentication, or his authorization, or some profile information. Or it might be environmental: a site might have figured out what time it is on the user’s site, and will adjust backgrounds and themes accordingly.
The context might be a simple variable. I have an example right here: is the browser you’re using good enough? (I know, this is considered Bad Form, but it’s what I have to work with) . The function has the simple name, need_browser_warning. The context key may as well have the same name. Using a constant for the context key is the usual pattern; this ensures the Django programmer won’t get it wrong more than once, at least on the view side. (The template is another issue entirely. Set your TEMPLATE_STRING_IF_INVALID in settings.py!)
I wanted something more clever in my context processor. Here’s sickly clever:
import inspect
def need_browser_warning(request):
return { inspect.currentframe().f_code.co_name:
not adequate_browser(request.META.get('HTTP_USER_AGENT')) }
Yeah, that’s a little twisted. It guarantees that the name of the context key is “need_browser_warning“, and the value is True or False depending upon what the function “adequate_browser” returns, which is what we want, so it’s all good.
Obviously, this isn’t good for everything. Some context processors handle many, many values. But for a one-key, this is a nifty way of ensuring name consistency.
3 Responses
Leo Shklovskii
September 17th, 2009 at 1:43 pm
1This is a nifty idea, but you can do it in a slightly less sickly clever way if you were to put it in a decorator, for example:
def same_name_in_context(fn):
def new_func(*args):
return { fn.func_name : fn(*args) }
return new_func
@same_name_in_context
def need_browser_warning(request):
return not adequate_browser(request.META.get(‘HTTP_USER_AGENT’))
Leo Shklovskii
September 17th, 2009 at 1:43 pm
2ugh, and the comment form killed all of my spacing… should still be pretty clear :-/
Elf Sternberg
September 17th, 2009 at 2:21 pm
3That’s true, but oddly enough, it’s actually less performant. I ran the numbers, and the inspect method is twice as efficient under cProfile. Not that that’s a good excuse for obfuscation, but it’s a point in inspect’s favor.
RSS feed for comments on this post · TrackBack URI
Leave a reply
Categories
Archives
Links
Meta
Calendar