Fixed #23260: Added generator support to defaultfilters.unordered_list.

This commit is contained in:
Jaap Roes 2014-08-08 15:40:44 +02:00 committed by Tim Graham
parent fe38be96c1
commit b3660d28f3
2 changed files with 34 additions and 25 deletions

View File

@ -678,41 +678,44 @@ def unordered_list(value, autoescape=None):
second_item = new_second_item
return [first_item, second_item], old_style_list
def _helper(list_, tabs=1):
def walk_items(item_list):
item_iterator = iter(item_list)
for item in item_iterator:
try:
next_item = next(item_iterator)
except StopIteration:
next_item = None
if not isinstance(next_item, six.string_types):
try:
iter(next_item)
except TypeError:
pass
else:
yield item, next_item
continue
yield item, None
if next_item:
yield next_item, None
def list_formatter(item_list, tabs=1):
indent = '\t' * tabs
output = []
list_length = len(list_)
i = 0
while i < list_length:
title = list_[i]
for item, children in walk_items(item_list):
sublist = ''
sublist_item = None
if isinstance(title, (list, tuple)):
sublist_item = title
title = ''
elif i < list_length - 1:
next_item = list_[i + 1]
if next_item and isinstance(next_item, (list, tuple)):
# The next item is a sub-list.
sublist_item = next_item
# We've processed the next item now too.
i += 1
if sublist_item:
sublist = _helper(sublist_item, tabs + 1)
sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (indent, sublist,
indent, indent)
output.append('%s<li>%s%s</li>' % (indent,
escaper(force_text(title)), sublist))
i += 1
if children:
sublist = '\n%s<ul>\n%s\n%s</ul>\n%s' % (
indent, list_formatter(children, tabs + 1), indent, indent)
output.append('%s<li>%s%s</li>' % (
indent, escaper(force_text(item)), sublist))
return '\n'.join(output)
value, converted = convert_old_style_list(value)
if converted:
warnings.warn(
"The old style syntax in `unordered_list` is deprecated and will "
"be removed in Django 2.0. Use the the new format instead.",
RemovedInDjango20Warning)
return mark_safe(_helper(value))
return mark_safe(list_formatter(value))
###################

View File

@ -549,6 +549,12 @@ class DefaultFiltersTests(TestCase):
b = ULItem('b')
self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
def item_generator():
yield a
yield b
self.assertEqual(unordered_list(item_generator()), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
# Old format for unordered lists should still work
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")