2011-12-28 123 views
17

我有下面的代碼模板中的值Django的模板 - 增量的變量

{% set counter = 0 %} 
{% for object in object_list %} 
    {% if object.attr1 == list1.attr1 and object.attr2 = list2.attr2 %} 
     <li><a href="{{ object.get_absolute_url }}"> Link {{counter++}} </a></li> 
    {% endif %} 
{% endfor %} 

我用這個custom tag什麼,我想要做的是隻有當遞增值設置一個變量的值滿足if循環。我知道{{counter++}}不起作用。但是,我怎麼能寫一個自定義標籤來完成相同的任務呢?

回答

24

不鼓勵更改Django模板中對象的狀態。你應該咬緊牙關,事先計算條件,並將額外的狀態傳遞給模板,以便簡化模板邏輯。

我在這方面並不是純粹的方式,但我已經被Django模板的有意義的限制幾次咬了。在我看來,你最好不要反對它。

由於您的意圖似乎是過濾出不匹配的項目,所以可以選擇將其過濾掉,然後使用{{ forloop.counter }}來整理所需的鏈接文本。因此,在視圖中,您有這樣的事情:

new_lst = filter(lambda x: x.attr0 == attr0 and x.attr1 == attr1, lst) 

,然後在你的模板:

{% for object in new_lst %} 
    <li><a href="{{ object.get_absolute_url }}"> Link {{ forloop.counter }} </a></li> 
{% endfor %} 
+1

+1很好的答案,[參考](https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for) ,赦免雙關 – 2011-12-28 18:21:39

+0

我通常不會試圖繞過Django的限制,但這次我真的需要這樣做......在我的情況下,{{forloop.counter}}沒有任何幫助。然而,我已經給了我的模板代碼,你能告訴我是否可以使用'{{forloop.counter}}' – Sachin 2011-12-28 18:29:33

+0

+1使用forloop計數器是這裏的方法。 @Sachin:如果你想要基於零的使用'{{forloop.counter0}}',但是。 – 2011-12-28 18:31:07

0

我剛剛發現自己的答案。正如我所說我正在使用this custom tag,它爲變量賦值。實際上做的是給context中的變量賦予一個值,所以我只是從上下文中檢索了值並對其進行了遞增。

這裏是它可以這樣{% increment <var_name> %}使用的代碼

class IncrementVarNode(template.Node): 

    def __init__(self, var_name): 
     self.var_name = var_name 

    def render(self,context): 
     value = context[self.var_name] 
     context[self.var_name] = value + 1 
     return u"" 

def increment_var(parser, token): 

    parts = token.split_contents() 
    if len(parts) < 2: 
     raise template.TemplateSyntaxError("'increment' tag must be of the form: {% increment <var_name> %}") 
    return IncrementVarNode(parts[1]) 

register.tag('increment', increment_var) 

但以前使用作爲{% set <var_name> = <var_value> %}

+0

我收到了一些奇怪的行爲。我的更新不會保存在嵌入的for循環中,就像臨時複製了輔助命名空間,然後一旦for循環消失就會被擦除,有什麼想法? – Jeremy 2014-12-16 03:29:26

10

上面提到的自定義標籤雖然這已經回答了這個VAR_NAME應該被設置爲一個值並反對已經說過的話,我只是有一個想法,並不能看到太多的傷害,如果你也許做了簡單的計數器類像

class Counter: 
    count = 0 

    def increment(self): 
     self.count += 1 
     return '' 

    def decrement(self): 
     self.count -= 1 
     return '' 

    def double(self): 
     self.count *= 2 
     return '' 

然後在模板{{ counter.increment }}{{ counter.count }}

+1

但是,我將如何鏈接這與模板節點? – Sachin 2011-12-29 18:51:45

+0

這並不意味着作爲剛剛作爲背景的一部分通過的標籤工作 – 2011-12-29 19:09:51

+0

哦!那個解決方案我已經有了我想要的東西與模板相關 – Sachin 2011-12-29 19:32:56