Skip to content

Instantly share code, notes, and snippets.

@sahid
Created October 29, 2010 09:45
Show Gist options
  • Save sahid/653233 to your computer and use it in GitHub Desktop.
Save sahid/653233 to your computer and use it in GitHub Desktop.
A Django Template tag to create or reuse all node of the template (with memcache)
import logging
from google.appengine.api import memcache
from django.conf import settings
from django import template
class HTMLListNode (template.Node):
""" Create or reuse all node of the template.
For each node generated by the template, the data are added into memcache
If the node into memcache is always valid it will be reused.
Example:
Before:
That is bad because, need to make for each node a request to memcache one by one.
{% for item in object_list %}
{% cache 9800 item.login item.updated %}
{% include "templates/block.html" %}
{% endcache%}
{% endfor %}
After:
That use the method get_multi and set_multi from memcache.
{% html_list request, items.object_list, "templates/block.html" "%(login)s %(updated)s" %}
"""
def __init__(self, request, items, path, cache):
self.request = template.Variable (request)
self.items = template.Variable (items)
self.path = template.Variable (path)
self.cache = template.Variable (cache)
def render (self, context):
request = self.request.resolve (context)
items = self.items.resolve (context)
path = unicode (self.path.resolve (context))
cache = unicode (self.cache.resolve (context))
template_cache = path + "." + cache
data_keys = [template_cache % x for x in items]
data_cached = memcache.get_multi (data_keys)
data_notcached = {}
c = template.RequestContext (request, locals ())
t = template.loader.get_template (path)
result = []
for item in items:
k = template_cache % item
if data_cached.has_key (k):
result.append (data_cached[k])
else:
c['item'] = item
data_notcached[k] = t.render (c)
result.append (data_notcached[k])
if data_notcached:
memcache.set_multi (data_notcached)
return "".join (result)
def do_list (parser, token):
try:
tag_name, request, items, template_path, cache = token.split_contents ()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires a 4 arguments" % token.contents.split ()[0]
return HTMLListNode (request, items, template_path, cache)
register.tag ('html_list', do_list)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment