Reputation: 50612
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)
Upvotes: 4
Views: 12155
Reputation: 338
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',}),
Upvotes: 0
Reputation: 2849
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
Upvotes: 2
Reputation: 10331
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)
Upvotes: 2
Reputation: 10794
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..})
Upvotes: 4
Reputation: 4360
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
.
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
Upvotes: 5