Login

Better render_to_response

Author:
SmileyChris
Posted:
March 24, 2007
Language:
Python
Version:
.96
Score:
1 (after 1 ratings)

I'm finding this much more efficient (from a coding perspective) than using the render_to_response shortcut.

It looks complex, but it's simple to use: just look at the example in the docstring.

Call this script renderer.py and chuck it in your project root.

 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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from django.template import loader, Context, RequestContext, TemplateSyntaxError
from django.http import HttpResponse

def new_renderer(template_prefix=None, always_use_requestcontext=True):
    """
    Create a decorator which can be used as a shortcut to render templates to
    an HttpResponse.

    The decorated function must return either:
     * an HttpResponse object,
     * a string containing the template name (if doesn't start with '/' then
       will be combined with the template_prefix) or
     * a tuple comprising of:
         * a string or tuple containing the template name(s),
         * a dictionary to add to the Context or RequestContext and
         * (optionally) a list of context processors (if given, forces use of
           RequestContext).

    Example usage (in a views module)::

        from projectname.renderer import new_renderer
        render_response = new_renderer('app_name/')     # Template dir.

        @render_response
        app_view(request):
            ...
            return 'app_view_template.htm', dict(object=object)
"""
    def renderer(func):
        def _dec(request, *args, **kwargs):
            response = func(request, *args, **kwargs)

            if isinstance(response, HttpResponse):
                return response
            elif isinstance(response, basestring):
                template_name = response
                namespace = {}
                context_processors = None
            elif isinstance(response, (tuple, list)):
                len_tuple = len(response)
                if len_tuple == 2:
                    template_name, namespace = response
                    context_processors = None
                elif len_tuple == 3:
                    template_name, namespace, context_processors = response
                else:
                    raise TemplateSyntaxError, '%s.%s function did not return a parsable tuple' % (func.__module__, func.__name__)
            else:
                raise TemplateSyntaxError, '%s.%s function did not provide a template name or HttpResponse object' % (func.__module__, func.__name__)

            if always_use_requestcontext or context_processors is not None:
                context = RequestContext(request, namespace, context_processors)
            else:
                context = Context(namespace)

            if template_prefix:
                if isinstance(template_name, (list, tuple)):
                    template_name = map(correct_path, template_name)
                else:
                    template_name = correct_path(template_name)

            return HttpResponse(loader.render_to_string(template_name, context_instance=context))

        return _dec

    def correct_path(template_name):
        if template_name.startswith('/'):
            return template_name[1:]
        return '%s%s' % (template_prefix, template_name)

    return renderer

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.