Question

It seems most documentation recommends :

template_values = {}
template_values["foo"] = "bar"
return render_to_response(path, template_values, context_instance=RequestContext(request)

Why don't I use :

template_values = RequestContext(request)
template_values["foo"] = "bar"
return render_to_response(path, template_values)
Was it helpful?

Solution

RequestContext doesn't inherit from dict, and as such is not guaranteed to implement all of dict's methods (and it doesn't), and any functions that operate on dicts may not work, either. Lastly, there's no reason to; it's better to consider it an opaque object whose implementation may change. Using a dict to provide the template's context has all the benefits and none of the drawbacks of RequestContext.

Update

To produce less boilerplate code, here are two utility functions I use. I put them in a shortcuts.py file at the base of my project.

from django.template import RequestContext
def render_template(request, template, data=None):
    "Wrapper around render_to_response that fills in context_instance for you."
    response = render_to_response(template, data,
                              context_instance=RequestContext(request))
    return response

def boilerplate_render(template):
    "Factory function for creating simple views that only forward to a template"
    def view(request, **kwargs):
        response = render_template(request, template, kwargs)
        return response
    return view

Usage:

def my_view(request):
    # Do stuff here...
    return render_template(request, 'my_template.html', {'var1': 'value', etc..})

my_view2 = boilerplate_render('my_template2.html') # Takes no context parameters

OTHER TIPS

In regards to "boiler-plate code", this is already built in to Django. Just use the generic view:

from django.views.generic.simple import direct_to_template

def my_view(request):
    # Do stuff here...
    return direct_to_template(request, 'my_template.html', {'var1': 'value', etc..})

Been banging my head on Django boilerplate for a while now. Django has (at least) three very similar functions for template rendering, each with a varying degree of shortcutedness:

django.shortcuts.render_to_response
django.template.loader.render_to_string
django.views.generic.simple.direct_to_template

It seems that at least two of these (probably render_to_response and direct_to_template) could be refactored into a single, less boilerplatish, shortcut.

django.views.generic.simple.direct_to_template is almost good enough on its own, but unfortunately puts keyword arguments in a params dict, making it incompatible with most uses of render_to_response (template refactoring is often necessary when switching from render_to_response to direct_to_template). render_to_response, which ironically lives in django.shortcuts, is hardly a well-thought-out shortcut. It should convert keyword arguments to template parameters and that ungainly context_instance argument is just too long to type ... often.

I've attempted a more useful shortcut. Note the use of *request_and_template_and_params to prevent clashes between template parameter names and positional argument names.

def render(*request_and_template_and_params, **kwargs):
    """Shortcut for rendering a template with RequestContext

    Takes two or three positional arguments: request, template_name, and
    optionally a mapping of template parameters. All keyword arguments,
    with the excepiton of 'mimetype' are added to the request context.

    Returns a HttpResponse object.
    """
    if len(request_and_template_and_params) == 2:
        request, template_name = request_and_template_and_params
        params = kwargs
    else:
        request, template_name, params = request_and_template_and_params
        params = dict(params) # copy because we mutate it
        params.update(kwargs)
    httpresponse_kwargs = {'mimetype': params.pop('mimetype', None)}
    context = RequestContext(request, params)
    return HttpResponse(loader.render_to_string(
        template_name, context_instance=context), **httpresponse_kwargs)

I just found this solution here and i modificate it just a litle:

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(template_name, output,
                    context_instance=RequestContext(request))
        return wrapper
    return renderer

@render_to('my_template.html')
def my_view(request):
    # View code here...
    return some_dict

Further to the "boiler plate" code, you could render to a template in your urls.py

For example:

url(r'^about/$', direct_to_template, {'template': 'about.html',}),
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top