Getting RequestContext in Your Templates
Lately, we’ve been taking over projects from people who began building their first site in Django, but either got in over their head or just found they didn’t have the time to continue. As I review the existing code, the first issue I typically see is using the render_to_response shortcut without including the RequestContext, preventing context processors from being used in the templates. The standard symptom is when people can’t access MEDIA_URL in their templates.
Here are a few ways to add RequestContext to your templates.
Option #1: Adding RequestContext to render_to_response
The Django documentation recommends passing RequestContext as an argument to render_to_response like this:
from django.shortcuts import render_to_response from django.template import RequestContext def my_view(request): # View code here... return render_to_response('my_template.html', my_data_dictionary, context_instance=RequestContext(request))
This works, but as you can see, it adds a fair amount of repetitive code to your views.
Option #2: Wrapper for render_to_response
Don’t repeat yourself. Create a wrapper like this, courtesy of Django Snippet #3
from django.shortcuts import render_to_response from django.template import RequestContext def render_response(req, *args, **kwargs): kwargs['context_instance'] = RequestContext(req) return render_to_response(*args, **kwargs)
Option #3: Use Generic Views
Django’s generic views include RequestContext by default. Although the docs show them being used in urls.py, you can just as easily use them in your views. James Bennet gave some examples of this technique on his blog back in ’06. It looks something like this:
from django.views.generic import list_detail def my_view(request): # View code here... return list_detail.object_list_(request, queryset=Foo.objects.all(), extra_context=some_dict)
Most views can be distilled down to either a single object or list of objects with some extra variables thrown in. When they can’t, simply use direct_to_template.
Option #4: Getting Creative with Decorators
I came across a technique I hadn’t seen before a couple of days ago when poking around django-cashflow. It monkey patches render_to_response using option #1 above, then creates uses a decorator for it. The code looks like this:
def render_to(template_name): def renderer(func): def wrapper(request, *args, **kw): output = func(request, *args, **kw) if not isinstance(output, dict): return output return render_to_response(request, template_name, output) return wrapper return renderer @render_to('my_template.html') def my_view(request): # View code here... return some_dict
Pretty slick.
How About You?
I use generic views for a few of reasons.
- It is less verbose than option #1
- Options 2 & 4 are clever, but I prefer to use built-ins whenever possible. One of the reasons I chose Python over Ruby is because it isn’t a TIMTOWTDI language. Wrappers and shortcuts are great, but they can also make it more difficult for someone else to jump into your code and start working. With generic views, you get sane defaults and everything is already fully documented and clear to other Django developers.
- They provide a standardized naming scheme for your templates. Again allowing other developers to jump right into your code without having to learn your style.
So how about you? What technique do you use and why?
Comments
Got something to say?
This was written on May, 10 2008 and is filed in code, django.
Our Products
Categories
- SEO
- accessiblity
- code
- company news
- django
- gondola
- open source
- portfolio
- presentation
- screencast
- software
- subversion
- trailmapping
- wordpress
Archives
- June, 2009
- April, 2009
- February, 2009
- December, 2008
- November, 2008
- September, 2008
- August, 2008
- July, 2008
Elsewhere
What we’ve been up to online
-
@37signals, seeing a number of 500 errors clicking around Basecamp right now http://skitch.com/t/u7e
Pete, 1 day, 15 hours ago -
Basecamp 500 Internal Server Error
Pete, 1 day, 15 hours ago -
Gmail broke plain text replies. Plz fix! http://bit.ly/43nd3q
Pete, 1 week ago -
Building an Open Source Consulting Company
Pete, 1 week, 3 days ago -
< 30% of applicants correctly followed the instructions. Should have added "attention to detail" & "ability to follow instructions" as reqs
Pete, 1 week, 6 days ago -
Django snippets: Sorl Thumbnail + Amazon S3
Pete, 1 week, 6 days ago -
Lincoln Loop is still looking for a Project Manager. Interested? http://authenticjobs.com/jobs/3688/
Pete, 1 week, 6 days ago -
Use PERT technique for more accurate estimates
Taking a weighted average of the most pessimistic, most optimistic, and most likely estimates of a task to get a realistic estimate of the time it will take.
Pete, 2 weeks, 3 days ago -
Evidence Based Scheduling - Joel on Software
Interesting approach to software estimation.
Pete, 2 weeks, 3 days ago -
Less Wrong: Planning Fallacy
People are terrible planners/estimators and there is evidence to prove it.
Pete, 2 weeks, 3 days ago -
A reminder of how simple business can be when you don't make it complicated - (37signals)
Refreshing, especially after after spending 2 days wading through client contracts and work orders.
Pete, 3 weeks, 5 days ago -
We're looking for a part-time Project Mgr to help us juggle the workload. Interested? info+pm@lincolnloop.com
Pete, 4 weeks, 1 day ago -
pushed to master at lincolnloop/django-protected-files
Pete, 1 month ago -
@richleland do you have libjpeg installed?
Pete, 1 month ago -
I have seen the future and it is Google Wave http://wave.google.com
Pete, 1 month ago


What about django.views.generic.simple.direct_to_template?
I’ve always used
render_to_response('template’, RequestContext(request, data_dict))
which seems to work fine, and isn’t so bad.
Like David suggested, just use the direct_to_template view as you would the render_to_response template (but passing request as the first argument).
Easy peasy.
David, I mentioned direct_to_template in Option 3 (my personal choice), but only use it when one of the other generic views doesn’t make more sense.
+1 for direct_to_template! simple + beautiful and without inventing the wheel.
I do this. I do repeat the “context = RequestContext(request)” line in (most)every view but I like being explicit like that.
context = RequestContext(request)
context[“somevar”] = “foo”
context[“othervar”] = “bar”
return render_to_response(“template.html”, context)
Nice writeup. Another good resource to point people to.
thanks for your code!
it helps me a lot in using RequestContext
In fact, direct_to_template is more a replacement for #1 given the fact it does exactly the same as #2, otherwise, if a generic_view already exists (#3), it’s more interesting to use it like you mention.
David, direct_to_template is a generic view.
django.views.generic.simple.direct_to_template :)
i like the decorator thingy, looks so pretty, can u provide a better example with the view, no matter what i return i always get “object has no attribute 'status_code’”
i am no django expert, but this make me think the view function must respond with a HttpResponse, which in turn needs a rendered template, then what is the purpose of render_to (I COULD SERIOUSLY BE MAKING MISTAKES)