From 7a7b331cd5975477597dac4dec7ee0ddb67f59e0 Mon Sep 17 00:00:00 2001 From: Bo Marchman Date: Wed, 15 Mar 2017 13:01:21 -0400 Subject: [PATCH] Fixed #27882 -- Allowed {% cache %} to cache indefinitely. --- django/templatetags/cache.py | 9 +++++---- docs/topics/cache.txt | 9 +++++++-- tests/template_tests/syntax_tests/test_cache.py | 11 +++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/django/templatetags/cache.py b/django/templatetags/cache.py index 3af6dc4df6..9e402a1206 100644 --- a/django/templatetags/cache.py +++ b/django/templatetags/cache.py @@ -20,10 +20,11 @@ class CacheNode(Node): expire_time = self.expire_time_var.resolve(context) except VariableDoesNotExist: raise TemplateSyntaxError('"cache" tag got an unknown variable: %r' % self.expire_time_var.var) - try: - expire_time = int(expire_time) - except (ValueError, TypeError): - raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time) + if expire_time is not None: + try: + expire_time = int(expire_time) + except (ValueError, TypeError): + raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time) if self.cache_name: try: cache_name = self.cache_name.resolve(context) diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index 6c8c736363..42f178ee30 100644 --- a/docs/topics/cache.txt +++ b/docs/topics/cache.txt @@ -659,8 +659,9 @@ the ``cache`` template tag. To give your template access to this tag, put The ``{% cache %}`` template tag caches the contents of the block for a given amount of time. It takes at least two arguments: the cache timeout, in seconds, -and the name to give the cache fragment. The name will be taken as is, do not -use a variable. For example: +and the name to give the cache fragment. The fragment is cached forever if +timeout is ``None``. The name will be taken as is, do not use a variable. For +example: .. code-block:: html+django @@ -669,6 +670,10 @@ use a variable. For example: .. sidebar .. {% endcache %} +.. versionchanged:: 2.0 + + Older versions don't allow a ``None`` timeout. + Sometimes you might want to cache multiple copies of a fragment depending on some dynamic data that appears inside the fragment. For example, you might want a separate cached copy of the sidebar used in the previous example for every user diff --git a/tests/template_tests/syntax_tests/test_cache.py b/tests/template_tests/syntax_tests/test_cache.py index 7dec02eb10..6a59cb3c75 100644 --- a/tests/template_tests/syntax_tests/test_cache.py +++ b/tests/template_tests/syntax_tests/test_cache.py @@ -122,6 +122,17 @@ class CacheTagTests(SimpleTestCase): output = self.engine.render_to_string('cache18') self.assertEqual(output, 'cache18') + @setup({ + 'first': '{% load cache %}{% cache None fragment19 %}content{% endcache %}', + 'second': '{% load cache %}{% cache None fragment19 %}not rendered{% endcache %}' + }) + def test_none_timeout(self): + """A timeout of None means "cache forever".""" + output = self.engine.render_to_string('first') + self.assertEqual(output, 'content') + output = self.engine.render_to_string('second') + self.assertEqual(output, 'content') + class CacheTests(SimpleTestCase):