【问题标题】:to perform addition operation on forloop.counter in django template在django模板中对forloop.counter进行加法操作
【发布时间】:2012-07-04 19:27:02
【问题描述】:

我想在给定条件下在 django 模板中执行减少 forloop.counter 的值,在 django 中是否可以。

下面是示例

{% for i in item %}
    {% if forloop.counter0|divisibleby:4 %}
        Start
    {% endif %}
        {% if i %}
            item{{ forloop.counter }}
        {% else %}
            ######### Here I want to reduce value of forloop.counter by 1 ###########
        {% endif %}
    {% if forloop.counter|divisibleby:4 %}
        End
    {% endif %}

{% endfor %} 

在上面的代码中,8个完美的项目输出将是

Start
item1
item2
item3
item4
End
Start
item5
item6
item7
item8
End

但假设 item2 为 None,则输出为

Start
item1 
item3
item4
End
Start
item5
item6
item7
item8
End

如果条件不满足,我想通过每次减少 forloop 的值以正确的升序形式打印它(每一步递增 1)。请不要建议自定义模板标签,我知道,我认为这是最后的选择。

【问题讨论】:

  • 您是否尝试过通过add 使用参数-1 进行过滤?
  • 使用 add:-1 将 forloop.counter 的值减少 -1。

标签: python django django-templates


【解决方案1】:

如果django模板不能实现,自己写一个试试看这里django custom template tag

【讨论】:

  • 我想知道在 django 中是否可行,当然这对我来说是最后的选择。
  • 请再看一遍问题..!
【解决方案2】:

可能是这样的:

{% for i in item %}
    {% cycle 'Start' '' '' '' %}
    {% if i %}
            item{{ forloop.counter }}
    {% else %}
            empty item{{ forloop.counter }}
    {% endif %}
    {% cycle '' '' '' 'End' %}
{% endfor %} 

这是输出:

Start
item1 
empty item2 
item3
item4
End 
Start
item5 
item6 
item7 
item8
End 

更新:我发现了一些非常有趣的东西,如何使用“本地”变量实际减少 forloop.counter:

{% cycle 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 as dec %}

{% for i in item %}
    {% cycle 'Start' '' '' '' %}
    {% if i %}
        item{{ forloop.counter|add:dec }}
    {% else %}
        <!-- empty {% cycle dec %} here we move to the next decrementing value -->
    {% endif %}
    {% cycle '' '' '' 'End' %}
{% endfor %} 

【讨论】:

  • 对不起,我无法理解循环在这里的工作原理,您没有再次获得 2,这是一个问题
  • 期望的输出是什么?我不确定我是否了解您想要实现的目标。我已经更新了答案 - 现在检查一下。
  • 没有@Tisho,看到更新的问题,它说数字应该增加1。现在你明白了。
  • 您需要第二个独立计数器然后...或者在将它们传递给模板之前从列表中删除无值。或者使用自定义标签...我找到了一种有趣的方法来实际减少 forloop.counter,但它适用于有限的项目:)
  • 好的,最后我没有使用 forloop.counter,而是采用了@brunodesthuilliers 告诉我的技术。我认为这是唯一的方法。您还发布了您的解决方案,可能对我也有用:)
【解决方案3】:

我真的怀疑 django 会不会让你这么容易弄乱forloop.counter,而且无论如何也不会弄乱它。显而易见的解决方案是在迭代之前过滤掉您的列表,这可以在您的视图中完成,或者(如果您坚持在模板中这样做)使用自定义过滤器。

或者您可以将列表包装在一个生成器函数中,该函数将负责过滤和编号,即:

def filteriternum(seq):
    num = 0
    for item in seq:
        if not item:
            continue
        num += 1
        yield num, item

在这里,您既可以在视图中进行包装,也可以编写一个自定义的标签模板过滤器来进行包装。

【讨论】:

  • 我想过这样做,但是迭代一个长列表会导致两次迭代,无论我是在视图中还是在模板中使用过滤器
  • @ParitoshSingh 然后将您的列表包装在过滤(或重新编号)生成器中
  • 尽管这不是我想要的 100%,但我觉得这是最合适的答案。谢谢@bruno :)
  • @ParitoshSingh 感谢您接受我的回答。您能否详细说明为什么它不能“100%”满足您的需求?我可能误解或忽略了您的问题中的某些内容,但我只是不明白究竟是什么......
  • 不,你的答案是完美的,但我认为 django 中会有一些过程来减少 forloop.counter 的值,但我认为没有这样的安全过程,所以你的答案似乎是正确的。
【解决方案4】:

改编自 Tisho 的回答:

{% for i in item %}
    {% if i %}
        {% cycle 'Start' '' '' '' %}
            item{% cycle 1 2 3 4 5 6 7 8 %}
        {% cycle '' '' '' 'End' %}
    {% endif %}
{% endfor %}

那会输出:

Start
item1 
item2
item3 
item4 
End 
Start
item5
item6 
item7 
item8 
End

所以没有洞了!但这仅在您的值数量有限的情况下才有效,因为您必须将它们全部写入第二个使用的 cycle 标记中...

【讨论】:

    猜你喜欢
    • 2019-02-26
    • 2011-07-13
    • 2010-11-16
    • 2014-07-23
    • 1970-01-01
    • 2022-08-07
    • 2011-01-30
    • 1970-01-01
    • 2019-04-16
    相关资源
    最近更新 更多