From dbfcedb499944f31444d347aa6c389303c6cf22e Mon Sep 17 00:00:00 2001 From: kapil garg Date: Fri, 7 Apr 2017 04:34:29 +0530 Subject: [PATCH] Fixed #28001 -- Updated comment and tested context popping in ForNode.render(). --- django/template/defaulttags.py | 8 +++----- tests/template_tests/syntax_tests/test_for.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index e2be85b9c0..ffb5615040 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -211,11 +211,9 @@ class ForNode(Node): nodelist.append(node.render_annotated(context)) if pop_context: - # The loop variables were pushed on to the context so pop them - # off again. This is necessary because the tag lets the length - # of loopvars differ to the length of each set of items and we - # don't want to leave any vars from the previous loop on the - # context. + # Pop the loop variables pushed on to the context to avoid + # the context ending up in an inconsistent state when other + # tags (e.g., include and with) push data to context. context.pop() return mark_safe(''.join(nodelist)) diff --git a/tests/template_tests/syntax_tests/test_for.py b/tests/template_tests/syntax_tests/test_for.py index cf556f1b71..1ffe25e1a7 100644 --- a/tests/template_tests/syntax_tests/test_for.py +++ b/tests/template_tests/syntax_tests/test_for.py @@ -180,3 +180,20 @@ class ForTagTests(SimpleTestCase): def test_for_tag_unpack14(self): with self.assertRaisesMessage(ValueError, 'Need 2 values to unpack in for loop; got 1.'): self.engine.render_to_string('for-tag-unpack14', {'items': (1, 2)}) + + @setup({ + 'main': '{% with alpha=alpha.values %}{% include "base" %}{% endwith %}_' + '{% with alpha=alpha.extra %}{% include "base" %}{% endwith %}', + 'base': '{% for x, y in alpha %}{{ x }}:{{ y }},{% endfor %}' + }) + def test_for_tag_context(self): + """ + ForNode.render() pops the values it pushes to the context (#28001). + """ + output = self.engine.render_to_string('main', { + 'alpha': { + 'values': [('two', 2), ('four', 4)], + 'extra': [('six', 6), ('eight', 8)], + }, + }) + self.assertEqual(output, 'two:2,four:4,_six:6,eight:8,')