mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #27974 -- Kept resolved templates constant during one rendering cycle.
Thanks Florian Apolloner for the initial patch.
This commit is contained in:
		| @@ -176,7 +176,7 @@ class IncludeNode(Node): | ||||
|             if not callable(getattr(template, 'render', None)): | ||||
|                 # If not, we'll try our cache, and get_template() | ||||
|                 template_name = template | ||||
|                 cache = context.render_context.setdefault(self.context_key, {}) | ||||
|                 cache = context.render_context.dicts[0].setdefault(self, {}) | ||||
|                 template = cache.get(template_name) | ||||
|                 if template is None: | ||||
|                     template = context.template.engine.get_template(template_name) | ||||
|   | ||||
| @@ -212,3 +212,14 @@ class IfChangedTests(SimpleTestCase): | ||||
|         ]) | ||||
|         output = engine.render_to_string('template', dict(vars=[1, 1, 2, 2, 3, 3])) | ||||
|         self.assertEqual(output, "123") | ||||
|  | ||||
|     def test_include_state(self): | ||||
|         """Tests the node state for different IncludeNodes (#27974).""" | ||||
|         engine = Engine(loaders=[ | ||||
|             ('django.template.loaders.locmem.Loader', { | ||||
|                 'template': '{% for x in vars %}{% include "include" %}{% include "include" %}{% endfor %}', | ||||
|                 'include': '{% ifchanged %}{{ x }}{% endifchanged %}', | ||||
|             }), | ||||
|         ]) | ||||
|         output = engine.render_to_string('template', dict(vars=[1, 1, 2, 2, 3, 3])) | ||||
|         self.assertEqual(output, '112233') | ||||
|   | ||||
| @@ -308,3 +308,23 @@ class IncludeTests(SimpleTestCase): | ||||
|             "Recursion!  A1  Recursion!  B1   B2   B3  Recursion!  C1", | ||||
|             t.render(Context({'comments': comments})).replace(' ', '').replace('\n', ' ').strip(), | ||||
|         ) | ||||
|  | ||||
|     def test_include_cache(self): | ||||
|         """ | ||||
|         {% include %} keeps resolved templates constant (#27974). The | ||||
|         CounterNode object in the {% counter %} template tag is created once | ||||
|         if caching works properly. Each iteration increases the counter instead | ||||
|         of restarting it. | ||||
|  | ||||
|         This works as a regression test only if the cached loader | ||||
|         isn't used, so the @setup decorator isn't used. | ||||
|         """ | ||||
|         engine = Engine(loaders=[ | ||||
|             ('django.template.loaders.locmem.Loader', { | ||||
|                 'template': '{% for x in vars %}{% include "include" %}{% endfor %}', | ||||
|                 'include': '{% include "next" %}', | ||||
|                 'next': '{% load custom %}{% counter %}' | ||||
|             }), | ||||
|         ], libraries={'custom': 'template_tests.templatetags.custom'}) | ||||
|         output = engine.render_to_string('template', dict(vars=range(9))) | ||||
|         self.assertEqual(output, '012345678') | ||||
|   | ||||
| @@ -166,3 +166,18 @@ def minustwo_overridden_name(value): | ||||
|  | ||||
|  | ||||
| register.simple_tag(lambda x: x - 1, name='minusone') | ||||
|  | ||||
|  | ||||
| @register.tag('counter') | ||||
| def counter(parser, token): | ||||
|     return CounterNode() | ||||
|  | ||||
|  | ||||
| class CounterNode(template.Node): | ||||
|     def __init__(self): | ||||
|         self.count = 0 | ||||
|  | ||||
|     def render(self, context): | ||||
|         count = self.count | ||||
|         self.count = count + 1 | ||||
|         return count | ||||
|   | ||||
		Reference in New Issue
	
	Block a user