2010-09-15 63 views
7

我不知道它是否是可能的,但我希望能寫出像下面這樣:創建於Django模板飛名單

{% with var1 var2 var3 as some_list %} 
    {{ some_list|maximum }} 
{% endwith %} 

上飛創建列表從任意數量的模板變量和/或文字看起來都很有用,所以我希望我忽略了一些簡單的東西。

雖然失敗了,但是,我想知道如何創建一個接受任意數量參數的模板標籤。 (我玩過simple_tag,對於接受固定數量參數的標籤效果很好)。

我不想去創建解析器和繼承django.template.Node的麻煩,直到我確定沒有簡單的解決方案。

回答

13

如果你想添加一個新的變量(即some_list),你需要訪問模板的上下文,所以simple_tag是不夠的。

對我來說,第一種方法是嘗試在視圖中進行這種工作,以便儘可能簡化模板。

如果這是不恰當的,你必須手動編寫代碼,就像這樣:

@register.tag 
def make_list(parser, token): 
    bits = list(token.split_contents()) 
    if len(bits) >= 4 and bits[-2] == "as": 
    varname = bits[-1] 
    items = bits[1:-2] 
    return MakeListNode(items, varname) 
    else: 
    raise template.TemplateSyntaxError("%r expected format is 'item [item ...] as varname'" % bits[0]) 

class MakeListNode(template.Node): 
    def __init__(self, items, varname): 
    self.items = map(template.Variable, items) 
    self.varname = varname 

    def render(self, context): 
    context[self.varname] = [ i.resolve(context) for i in self.items ] 
    return "" 

並使用它像這樣來創建一個新的變量some_list

{% make_list var1 var2 var3 as some_list %} 

隨意給它一個更好的名字!

+2

+1。該解決方案可讓您將結果列表保存在另一個變量中,以便稍後對其進行操作。 – 2010-09-15 08:25:23

+0

謝謝,威爾。這很適合這個賬單。視圖中的處理不是一種選擇的原因是我爲可重用的Django應用程序創建了一個模板。該視圖提供了一個完整的項目列表。在模板中,我使用「{%with 5 as max%}」來設置要顯示的最大項目數。除了輸出適當數量的項目外,我還以「顯示Y項目的X」的形式顯示了一個顯示計數。 X是'items | length'或'max',以較小者爲準。所以我需要找到兩個值中較小的一個,其中之一是在模板本身中設置的。 – davidchambers 2010-09-15 09:05:22

+0

它應該是'len(bits)> 3',而不是'len(bits)> 4',以允許創建一個帶有單個項目的列表。 – davidchambers 2010-09-15 23:40:57

3

我玩了一下,想出了一個標籤,它可以接受可變數量的參數並將它們轉換爲列表。

@register.tag('to_list') 
def to_list(_parser, token): 
    try: 
     parts = token.split_contents() 
    except ValueError: 
     raise template.TemplateSyntaxError, \ 
      "%r tag requires at least one argument" % token.contents.split()[0] 

    return AsListNode(parts[1:]) 

class AsListNode(template.Node): 
    def __init__(self, parts): 
     self.parts = map(lambda p: template.Variable(p), parts) 

    def render(self, context): 
     resolved = [] 
     for each in self.parts: 
      resolved.append(each.resolve(context)) 
     return resolved 

模板:

<p>{% to_list var1 var2 var3 %}</p> 

更新

@威爾的solution更好。它允許您使用另一個變量保存結果列表,以便稍後對其進行操作。