2010-06-28 218 views

回答

22

你有兩個選擇:

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 

filter documentation

+0

謝謝!完美解決方案 – demos 2010-06-29 04:11:17

+0

您將如何在模板中使用解決方案2? – webtweakers 2014-02-26 09:28:50

6

濫用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。

+1

不錯的破解! :)有一天可能會派上用場。 – demos 2010-06-29 04:11:36

+0

好的黑客對我很有幫助 – 2015-04-30 09:14:44

1

自定義模板標籤

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的額外調用)。然而,我還沒有設法可靠地測試這一點,只有當你不得不擴大規模時纔會出現問題。