diff --git a/caching/ext.py b/caching/ext.py index ac6eaea..b8fe3d5 100644 --- a/caching/ext.py +++ b/caching/ext.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.utils import encoding from jinja2 import nodes from jinja2.ext import Extension @@ -40,10 +41,16 @@ def parse(self, parser): # If there is a comma, the user provided a timeout. If not, use # None as second parameter. - if parser.stream.skip_if('comma'): - args.append(parser.parse_expression()) - else: - args.append(nodes.Const(None)) + timeout = nodes.Const(None) + extra = nodes.Const([]) + while parser.stream.skip_if('comma'): + x = parser.parse_expression() + if parser.stream.current.type == 'assign': + next(parser.stream) + extra = parser.parse_expression() + else: + timeout = x + args.extend([timeout, extra]) body = parser.parse_statements(['name:endcache'], drop_needle=True) @@ -58,12 +65,13 @@ def process_cache_arguments(self, args): """Extension point for adding anything extra to the cache_support.""" pass - def _cache_support(self, name, obj, timeout, caller): + def _cache_support(self, name, obj, timeout, extra, caller): """Cache helper callback.""" if settings.TEMPLATE_DEBUG: return caller() - return caching.base.cached_with(obj, caller, 'fragment:' + name, - timeout) + extra = ':'.join(map(encoding.smart_str, extra)) + key = 'fragment:%s:%s' % (name, extra) + return caching.base.cached_with(obj, caller, key, timeout) # Nice import name. diff --git a/tests/test_cache.py b/tests/test_cache.py index c9b8e93..dac14ea 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -225,6 +225,29 @@ def check(obj, expected): addon.save() check(addon, '1\n17') + def test_jinja_cache_tag_extra(self): + env = jinja2.Environment(extensions=['caching.ext.cache']) + addon = Addon.objects.get(id=1) + + template = ('{% cache obj, extra=[obj.key] %}{{ obj.id }}:' + '{{ obj.key }}{% endcache %}') + + def check(obj, expected): + t = env.from_string(template) + eq_(t.render(obj=obj), expected) + + addon.key = 1 + check(addon, '1:1') + addon.key = 2 + check(addon, '1:2') + + template = ('{% cache obj, 10, extra=[obj.key] %}{{ obj.id }}:' + '{{ obj.key }}{% endcache %}') + addon.key = 1 + check(addon, '1:1') + addon.key = 2 + check(addon, '1:2') + def test_cached_with(self): counter = mock.Mock() def expensive():