Django

Code

root/django/trunk/django/templatetags/cache.py

Revision 8533, 2.2 kB (checked in by mtredinnick, 3 months ago)

Fixed #7460 -- Made the "cache" template tag always generate keys that can be
used with the memcache backend (which has the strongest restriction on keys).
Based on a patch from trbs.

  • Property svn:eol-style set to native
Line 
1 from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
2 from django.template import resolve_variable
3 from django.core.cache import cache
4 from django.utils.encoding import force_unicode
5 from django.utils.http import urlquote
6
7 register = Library()
8
9 class CacheNode(Node):
10     def __init__(self, nodelist, expire_time_var, fragment_name, vary_on):
11         self.nodelist = nodelist
12         self.expire_time_var = Variable(expire_time_var)
13         self.fragment_name = fragment_name
14         self.vary_on = vary_on
15
16     def render(self, context):
17         try:
18             expire_time = self.expire_time_var.resolve(context)
19         except VariableDoesNotExist:
20             raise TemplateSyntaxError('"cache" tag got an unknkown variable: %r' % self.expire_time_var.var)
21         try:
22             expire_time = int(expire_time)
23         except (ValueError, TypeError):
24             raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
25         # Build a unicode key for this fragment and all vary-on's.
26         cache_key = u':'.join([self.fragment_name] + [urlquote(resolve_variable(var, context)) for var in self.vary_on])
27         value = cache.get(cache_key)
28         if value is None:
29             value = self.nodelist.render(context)
30             cache.set(cache_key, value, expire_time)
31         return value
32
33 def do_cache(parser, token):
34     """
35     This will cache the contents of a template fragment for a given amount
36     of time.
37
38     Usage::
39
40         {% load cache %}
41         {% cache [expire_time] [fragment_name] %}
42             .. some expensive processing ..
43         {% endcache %}
44
45     This tag also supports varying by a list of arguments::
46
47         {% load cache %}
48         {% cache [expire_time] [fragment_name] [var1] [var2] .. %}
49             .. some expensive processing ..
50         {% endcache %}
51
52     Each unique set of arguments will result in a unique cache entry.
53     """
54     nodelist = parser.parse(('endcache',))
55     parser.delete_first_token()
56     tokens = token.contents.split()
57     if len(tokens) < 3:
58         raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0])
59     return CacheNode(nodelist, tokens[1], tokens[2], tokens[3:])
60
61 register.tag('cache', do_cache)
Note: See TracBrowser for help on using the browser.