【问题标题】:Django Template - Increment the value of a variableDjango 模板 - 增加变量的值
【发布时间】:2012-01-29 09:09:24
【问题描述】:

我的模板中有以下代码

{% 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++}} 不起作用。但是我怎样才能编写一个自定义标签来完成同样的任务呢?

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    不鼓励在 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 不错的答案,for reference,请原谅双关语
    • 我通常不会试图绕过 Django 的限制,但这次我真的需要这样做......在我的情况下,{{ forloop.counter }} 没有帮助。但是我已经给出了我的模板代码,你能告诉我是否可以使用{{ forloop.counter }}
    • +1 使用 forloop 计数器是这里的方法。 @Sachin:不过,如果你想从零开始使用{{ forloop.counter0 }}
    • 我不明白当我希望我的counter 值仅在满足if 条件时增加时,我该如何使用`{{ forloop.counter }}`
    • 澄清一下:我认为你不能使用forloop.counter 来解决这个问题。为什么只需要使用模板系统(包括标签)来解决这个问题?合法的问题,我很好奇 - 我不是在平移你的意图或任何东西。
    【解决方案2】:

    我自己刚刚找到了答案。正如我所说,我使用的是this custom tag,它为变量赋值。实际上所做的是设置为context 中的变量赋值,所以我只是从上下文中检索该值并将其递增。

    这里是代码

    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)
    

    它可以像 {% increment &lt;var_name&gt; %} 这样使用,但是这个 var_name 应该已经设置为之前使用上面提到的自定义标签 {% set &lt;var_name&gt; = &lt;var_value&gt; %} 的值

    【讨论】:

    • 我遇到了一些奇怪的行为。我的更新没有保存在嵌入式 for 循环中,就好像临时复制了一个辅助命名空间,然后在 for 循环消失后删除了,有什么想法吗?
    【解决方案3】:

    虽然这已经得到回答并且与所说的背道而驰,但我只是有一个想法,如果你制作简单的计数器类,也看不出太大的伤害

    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 }}

    【讨论】:

    • @TI:为什么要定义count = 0count 是即时变量、类变量还是静态变量?
    • 聪明的解决方案
    • 在模板中不起作用;增量有效,但 {{ counter.count }} 始终为 0,可能是 Dango 中的缓存或其他东西
    【解决方案4】:

    为了增加模板django的价值: 如果 varint=6,则结果为 8

    {{ varint|add:"2" }}
    

    为了减少模板django中的值:

    如果 varint=6,则结果为 5

      {{ varint|add:"-1" }}
    

    【讨论】:

      猜你喜欢
      • 2014-09-14
      • 2011-01-31
      • 2019-06-08
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      • 2016-11-29
      • 1970-01-01
      相关资源
      最近更新 更多