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