This code improves on Django's render_to_response shortcut function in the following ways:
- If the caller does not provide a MIME type, and the caller is passing a RequestContext, it interrogates the request to determine if the HTTP client supports application/xhtml+xml encoding. If so, it sets the request type to application/xhtml+xml to override the HttpRequest class's default mime type of text/html.
- It caches parsed templates in its own cache to improve performance.
If you aren't using XHTML in your templates, you may choose to comment out the code that tests for and sets the application/xhtml+xml MIME type.
I place this code in a file named "util.py" in my application. In my views, I write "from app.util import render_to_response" where I used to write "from django.shortcuts import render_to_response".
Note that the caching functionality provided by this code means that you will need to recycle your Django instance when you make template changes. Instructions for doing this depend on how you have deployed your Django application.
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 | import django.shortcuts
from django.http import HttpResponse
from django.template import loader
from django.template.context import Context
template_cache = { }
def render_to_response(*args, **kwargs) :
"""Implement two changes relative to django.shortcuts.render_to_response:
1) Use content-type 'application/xhtml+xml' if supported by the client.
2) Cache the compiled template.
"""
# Set content type to application/xhtml+xml if conditions allow.
if not kwargs.has_key('mimetype') and \
kwargs.has_key('context_instance') and \
kwargs['context_instance'].has_key('request') and \
kwargs['context_instance']['request'].META.has_key('HTTP_ACCEPT') and \
'application/xhtml+xml' in \
kwargs['context_instance']['request'].META['HTTP_ACCEPT'].split(',') :
kwargs['mimetype'] = 'application/xhtml+xml'
# Load template (use cache if possible).
template_path = args[0]
if template_cache.has_key(template_path) :
template = template_cache[template_path]
else :
template = loader.get_template(template_path)
template_cache[template_path] = template
# Render template using provided context.
if kwargs.has_key('context_instance') :
context_instance = kwargs['context_instance']
else :
context_instance = Context()
if len(args) > 1 :
context_instance.update(args[1])
rendering = template.render(context_instance)
# Return HttpResponse using rendered template.
httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
return HttpResponse(rendering, **httpresponse_kwargs)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Hmmm.. Templates are already precompiled by django. I don't think this will make the code any faster. Have you benchmarked it?
#
Hi adam. From my reading of the code in django.template.loader and django.template.loaders.filesystem, it seems to me that template files are loaded from disk on each request. So I think that my code is saving both the file load and also the template compile on every subsequent request.
Can you point me to something that shows otherwise? I certainly don't want to add unnecessary overhead! Thanks.
In my particular case this code did yield some performance improvement. I have much more significant bottlenecks still to track down, though.
#
Ok, here are some more formal results. I wrote two scripts, test.py:
and test2.py:
From the command line:
#
Ah! Your right that the template loaders do attempt to open the template name every time. One might hope that the kernel will have them cached once its warmed up a bit; but you're right (and your test demonstrates) that there is a performance increase.
#
Please login first before commenting.