diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 8ab1f1dbdc..5f743caffd 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -189,10 +189,10 @@ class ForNode(Node): if unpack: # If there are multiple loop variables, unpack the item into # them. - if not isinstance(item, (list, tuple)): - len_item = 1 - else: + try: len_item = len(item) + except TypeError: # not an iterable + len_item = 1 # Check loop variable count before unpacking if num_loopvars != len_item: raise ValueError( diff --git a/docs/releases/1.10.1.txt b/docs/releases/1.10.1.txt index fdc00861c6..eebe4e44d1 100644 --- a/docs/releases/1.10.1.txt +++ b/docs/releases/1.10.1.txt @@ -51,3 +51,5 @@ Bugfixes * Fixed annotations with database functions when combined with lookups on PostGIS (:ticket:`27014`). + +* Reallowed the ``{% for %}`` tag to unpack any iterable (:ticket:`27058`). diff --git a/tests/template_tests/syntax_tests/test_for.py b/tests/template_tests/syntax_tests/test_for.py index 03c2e6ee9b..4af7881e57 100644 --- a/tests/template_tests/syntax_tests/test_for.py +++ b/tests/template_tests/syntax_tests/test_for.py @@ -126,6 +126,11 @@ class ForTagTests(SimpleTestCase): output = self.engine.render_to_string('for-tag-filter-ws', {'s': 'abc'}) self.assertEqual(output, 'abc') + @setup({'for-tag-unpack-strs': '{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}'}) + def test_for_tag_unpack_strs(self): + output = self.engine.render_to_string('for-tag-unpack-strs', {'items': ('ab', 'ac')}) + self.assertEqual(output, 'a:b/a:c/') + @setup({'for-tag-unpack10': '{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}'}) def test_for_tag_unpack10(self): with self.assertRaisesMessage(ValueError, 'Need 2 values to unpack in for loop; got 3.'):