我想在同一個for循環中遍歷django模板中的多個列表。我該怎麼做?在django模板中遍歷同一個循環中的多個列表
一些思考這個鏈接:
{% for item1, item2, item3 in list1, list2 list3 %}
{{ item1 }}, {{ item2 }}, {{ item3 }}
{% endfor %}
是這樣的可能嗎?
我想在同一個for循環中遍歷django模板中的多個列表。我該怎麼做?在django模板中遍歷同一個循環中的多個列表
一些思考這個鏈接:
{% for item1, item2, item3 in list1, list2 list3 %}
{{ item1 }}, {{ item2 }}, {{ item3 }}
{% endfor %}
是這樣的可能嗎?
你有兩個選擇:
1.定義你的對象,以便您可以訪問參數等項目
for x in list:
{{x.item1}}, {{x.item2}}, {{x.item3}}
請注意,您必須通過三個相結合,以彌補列表清單:
lst = [{'item1': t[0], 'item2': t[1], 'item3':t[2]} for t in zip(list_a, list_b, list_c)]
2.您可以定義自己的過濾
個from django import template
register = template.Library()
@register.filter(name='list_iter')
def list_iter(lists):
list_a, list_b, list_c = lists
for x, y, z in zip(list_a, list_b, list_c):
yield (x, y, z)
# test the filter
for x in list_iter((list_a, list_b, list_c)):
print x
濫用Django模板:
{% for x in list_a %}
{% with forloop.counter|cut:" " as index %}
{{ x }},
{{ list_b|slice:index|last }},
{{ list_c|slice:index|last }} <br/>
{% endwith %}
{% endfor %}
,但從來沒有做到這一點!只需在您的視圖中使用zip。
不錯的破解! :)有一天可能會派上用場。 – demos 2010-06-29 04:11:36
好的黑客對我很有幫助 – 2015-04-30 09:14:44
自定義模板標籤
from django import template
register = template.Library()
def parse_tokens(parser, bits):
"""
Parse a tag bits (split tokens) and return a list on kwargs (from bits of the fu=bar) and a list of arguments.
"""
kwargs = {}
args = []
for bit in bits[1:]:
try:
try:
pair = bit.split('=')
kwargs[str(pair[0])] = parser.compile_filter(pair[1])
except IndexError:
args.append(parser.compile_filter(bit))
except TypeError:
raise template.TemplateSyntaxError('Bad argument "%s" for tag "%s"' % (bit, bits[0]))
return args, kwargs
class ZipLongestNode(template.Node):
"""
Zip multiple lists into one using the longest to determine the size
Usage: {% zip_longest list1 list2 <list3...> as items %}
"""
def __init__(self, *args, **kwargs):
self.lists = args
self.varname = kwargs['varname']
def render(self, context):
lists = [e.resolve(context) for e in self.lists]
if self.varname is not None:
context[self.varname] = [i for i in map(lambda *a: a, *lists)]
return ''
@register.tag
def zip_longest(parser, token):
bits = token.contents.split()
varname = None
if bits[-2] == 'as':
varname = bits[-1]
del bits[-2:]
else:
# raise exception
pass
args, kwargs = parse_tokens(parser, bits)
if varname:
kwargs['varname'] = varname
return ZipLongestNode(*args, **kwargs)
用法:
{% zip_longest list1 list2 as items %}
這可以讓你通過2名或多個列表標籤,然後在項目變量進行迭代。如果你使用兩個以上的列表,那麼不幸的是你需要循環。然而,隨着兩份名單,我使用的第一和最後一個過濾器內環路這樣的:
{% for item in items %}
{% with item|first as one %}
{% with item|last as two %}
<p>{{ one }}</p>
<p>{{ two }}</p>
{% endwith %}
{% endwith %}
{% endfor %}
然而,因建了這一切,它可能是更好的做到這一點的看法!
Python的Itertools
你也應該考慮Python的itertools,它具有izip_longest方法,它有兩個或多個列表。它使用最長的列表作爲一個返回列表來確定大小(如果您希望它連接到最短列表,那麼看起來不會比izip更遠)。您可以使用fillvalue
關鍵字來選擇填充空值的內容,但默認情況下爲None。
izip_longest和izip都返回一個迭代器而不是一個列表,所以你可以看到一些大型網站的性能提升。
重要的是要注意,izip_longest可能會稍微超過必要的數據庫,這取決於它如何確定每個列表的長度(執行count()將是對db的額外調用)。然而,我還沒有設法可靠地測試這一點,只有當你不得不擴大規模時纔會出現問題。
謝謝!完美解決方案 – demos 2010-06-29 04:11:17
您將如何在模板中使用解決方案2? – webtweakers 2014-02-26 09:28:50