1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 | from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
def auto_render(func):
"""Decorator that automaticaly call the render_to_response shortcut.
The view must return a tuple with two items : a template filename and the desired context.
HttpResponse object could be also returned. it's possible to override the default
template filename by calling a decorated view with an "template_name" parameter
or to get only the context dictionary via "only_context" parameter.
>>> from utils.utils import auto_render
>>> @auto_render
... def test(request):
... return 'base.html', {'oki':1}
...
>>> from django.http import HttpRequest, HttpResponse
>>> response = test(HttpRequest())
>>> assert type(response) is HttpResponse
>>> response = test(HttpRequest(), only_context=True)
>>> assert response['oki'] == 1
>>> try:
... response = test(HttpRequest(), template_name='fake_template.html')
... except Exception, e:
... e.message
'fake_template.html'
"""
def _dec(request, *args, **kwargs):
if kwargs.get('only_context', False):
# return only context dictionary
del(kwargs['only_context'])
response = func(request, *args, **kwargs)
if isinstance(response, HttpResponse) or isinstance(response, HttpResponseRedirect):
raise Except("cannot return context dictionary because a HttpResponseRedirect as been found")
(template_name, context) = response
return context
if kwargs.get('template_name', False):
overriden_template_name = kwargs['template_name']
del(kwargs['template_name'])
else:
overriden_template_name = None
response = func(request, *args, **kwargs)
if isinstance(response, HttpResponse) or isinstance(response, HttpResponseRedirect):
return response
(template_name, context) = response
if overriden_template_name:
template_name = overriden_template_name
return render_to_response(template_name, context, context_instance=RequestContext(request))
return _dec
|
Comments
I made a similar decorator, but it passes the template name as an argument to the decorator itself, instead of the return value...I find it slightly cleaner:
http://www.djangosnippets.org/snippets/1022/
#