【问题标题】:Django template: get total iteration count for nested loopsDjango模板:获取嵌套循环的总迭代次数
【发布时间】:2011-05-20 01:11:21
【问题描述】:

我在一个模板中有两个嵌套的 for 循环。我需要获得自父 for 循环开始以来的总迭代次数。只有当子 for 迭代时,计数器才需要递增。

例如:

每个循环从 1 到 3(包括在内)

父循环 - 第一次迭代

子循环 - 第三次迭代

想要的结果:3

父循环 - 第二次迭代

子循环 - 第一次迭代

想要的结果:4

有什么方法可以使用标准的 Django 模板标签来做到这一点?如果没有,我有什么选择?

【问题讨论】:

  • @jMyles 谢谢。你的帖子很旧,但它帮助我解决了我的问题。在模板中添加“divisibleby:”允许在循环数达到给定数量时执行某些特定操作(在下面的示例中为 12){% for basket in baskets %} {% for egg in basket.eggs.all %} {#如果鸡蛋总数是 12 的倍数,则表示找到了新的一打 #} {% if forloop.counter|add:forloop.parentloop.counter|divisibleby:12 %} 一打鸡蛋! {% endif %} {% endfor %} {% endfor %}

标签: django django-templates


【解决方案1】:

Write a count template tag 将累积在上下文变量中。

{% for ... %}
  {% for ... %}
    {% count totalloops %}
  {% endfor %}
{% endfor %}
{{ totalloops }}

【讨论】:

  • 我尝试编写一个自定义标签,在第二个循环的每次迭代中增加一个变量,但在父循环迭代时它会被重置。
【解决方案2】:

你可以使用 {{forloop.counter |add: forloop.parentcounter.counter }} 但如果你想重置计数器,那么你需要编写自己的自定义 python 方法,然后你可以调用它。来自 django 模板。

喜欢在你的意见添加-

class make_incrementor(object):
    count = 0

    def __init__(self, start):
        self.count = start

    def inc(self, jump=1):
        self.count += jump
        return self.count

    def res(self):
        self.count = 0
        return self.count

def EditSchemeDefinition(request, scheme_id):

    iterator_subtopic = make_incrementor(0)
    scheme_recs = scheme.objects.get(id=scheme_id)
    view_val = {
        'iterator_subtopic': iterator_subtopic,
        "scheme_recs": scheme_recs,
    }
    return render(request, "edit.html", view_val)

稍后在您的 django 模板中,我们可以调用“iterator_subtopic”方法来增加或重置其值,例如:-

<td id="subTopic" class="subTopic">
<p hidden value="{{ iterator_subtopic.res }}"></p>
{% for strand in  scheme_recs.stand_ids.all %}
    {{ iterator_subtopic.res }}
    {% for sub_strand in  strand.sub_strand_ids.all %}
        {% for topic in  sub_strand.topic_ids.all %}
            {% for subtopic in  topic.sub_topic_ids.all %}
                <input id="subTopic{{ iterator_subtopic.inc  }}" class="len"
                       value="{{ subtopic.name }}">
                <br>
            {% endfor %}
        {% endfor %}
    {% endfor %}
{% endfor %}

所以它会不断增加值,我们也可以在我们想要的地方重置它。

【讨论】:

    【解决方案3】:

    你知道,进去,会有多少个循环?

    如果是这样,一个简单的方法是:

    {{forloop.counter |add: forloop.parentcounter.counter }} 等

    相对于逻辑分离有点臭(@Ignacio 的建议肯定在这方面更好),但我认为如果保持整洁有序是可以接受的。

    【讨论】:

      【解决方案4】:

      使用基于类的视图(特别是使用 Python 3 和 Django 2.1),并使用 @Javed 的答案作为起点,您可以在视图中执行以下操作:

      class Accumulator:
      
          def __init__(self, start=0):
              self.reset(start)
      
          def increment(self, step=1):
              step = 1 if not isinstance(step, int) else step
              self.count += step
              return self.count
      
          def reset(self, start=0):
              start = 0 if not isinstance(start, int) else start
              self.count = start
              return self.count
      
      class MyView(ParentView):
      
          def get_context_data(self, **kwargs):
              context = super().get_context_data(**kwargs)
              context['counter'] = Accumulator()  # use start=-1 for a zero-based index.
              return context
      

      然后在模板中,你可以这样做:

      {% with counter.increment as count %}
        <input id="form-input-{{ count }}">
      {% endwith %}
      

      【讨论】:

      • 不知道你为什么花时间回答一个 9 岁的问题,但谢谢 :)
      • @Virgiliu 这是因为我需要为我当前的技术堆栈做同样的事情,所以在找到这个答案后,我想我会为 Python 3 / Django 2 提供这个更新。
      猜你喜欢
      • 2021-11-30
      • 2017-07-03
      • 1970-01-01
      • 2021-01-16
      • 2014-08-19
      • 2012-10-25
      • 1970-01-01
      • 2014-08-24
      • 2018-03-16
      相关资源
      最近更新 更多