2011-12-28 129 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