【问题标题】:Numeric for loop in Django templatesDjango模板中的数字for循环
【发布时间】:2010-11-09 14:44:27
【问题描述】:

如何在 Django 模板中编写数字 for 循环?我的意思是像

for i = 1 to n

【问题讨论】:

    标签: django django-templates


    【解决方案1】:

    我只是把流行的答案更进一步,让它更健壮。这使您可以指定任何起点,例如 0 或 1。它还使用了 python 的范围功能,其中 end 少了一个,因此它可以直接与列表长度一起使用。

    @register.filter(name='range')
    def filter_range(start, end):
        return range(start, end)
    

    然后在您的模板中只包含上面的模板标记文件并使用以下内容:

    {% load myapp_filters %}
    
    {% for c in 1|range:6 %}
        {{ c }}
    {% endfor %}
    

    现在您可以执行 1-6 而不仅仅是 0-6 或硬编码。添加一个步骤需要一个模板标签,这应该涵盖更多用例,所以这是一个进步。

    【讨论】:

    • 这是@guillermo-siliceo-trueba 答案的扩展。
    • 很好的答案,你节省了我的时间
    • 这是完美的答案
    【解决方案2】:

    您可以在views.py 的上下文中传递range(n) 而不是n。这将为您提供一个可迭代的列表。

    context['range']= range(n)
    

    然后你可以这样迭代你的模板:

    {% for i in range %}
       <!-- your code -->
    {% endfor %}
    

    【讨论】:

      【解决方案3】:

      我对这个问题的看法,我认为是最 Pythonic 的。在您的应用程序templatetags 目录中创建my_filters.py。

      @register.filter(name='times') 
      def times(number):
          return range(number)
      

      在您的模板中使用:

      {% load my_filters %}
      {% for i in 15|times %}
          <li>Item</li>
      {% endfor %}
      

      【讨论】:

      • 我认为这是正确的解决方案。执行range(1, 16) 以获取从 1 开始的数字,而不是 0。
      • 同时在templatetags目录下创建一个空文件_init _.py。还将这些行添加到 my_filters.py from django.template import Library;register = Library() 的顶部
      • 添加第二个过滤器参数,您将获得python内置的全范围函数。 @register.filter(name='range') def filter_range(start, end): return range(start, end) 然后被用作{% for i in 1|range:6 %}{% endfor %}。请参阅下面的完整答案....
      • 我稍微修改了一下(请原谅格式):try: return range(number) except: return []。这样它就不会引发错误并返回一个空数组(类似于大多数模板函数的工作方式)。
      • 为了有一个python解决方案,这在我看来是最好的一个
      【解决方案4】:
      {% for _ in ''|center:13 %}
          {{ forloop.counter }}
      {% endfor %}
      

      【讨论】:

      • 虽然此代码可能会为问题提供解决方案,但最好添加有关其工作原理/方式的上下文。这可以帮助未来的用户学习并最终将这些知识应用到他们自己的代码中。解释代码时,您也可能会得到用户的积极反馈/赞成。
      • @AmitVerma 我忘记了我在对您的评论的最后两个回复中所说的内容,即有人删除了您的评论。对此感到抱歉。
      【解决方案5】:

      这显示了 1 到 20 个数字:

      {% for i in "x"|rjust:"20"|make_list %}
       {{ forloop.counter }}
      {% endfor %}
      

      这也可以帮助您: (count_all_slider_objects 来自视图)

      {% for i in "x"|rjust:count_all_slider_objects %}
        {{ forloop.counter }}
      {% endfor %}
      

      或

        {% with counter=count_all_slider_objects %}
          {% if list_all_slider_objects %}
            {%  for slide in list_all_slider_objects %}
              {{forloop.counter|add:"-1"}}
              {% endfor%}
            {% endif %}
          {% endwith %}
      

      【讨论】:

        【解决方案6】:

        对于那些寻求简单答案的人,只需要显示一定数量的值,例如 100 个帖子中的 3 个,只需添加 {% for post in posts|slice:"3" %} 并正常循环,只会添加 3 个帖子。

        【讨论】:

          【解决方案7】:
          {% for i in range(10) %}
             {{ i }}
          
          {% endfor %}
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
          • 无法解析余数:(10) from range(10)
          【解决方案8】:

          我使用了一种简单的技术,可以很好地适用于没有特殊标签和额外上下文的小案例。有时这会派上用场

          {% for i in '0123456789'|make_list %}
              {{ forloop.counter }}
          {% endfor %}
          

          【讨论】:

          • FWIW, 012 == 12,所以它只会循环 1 和 2。
          • {% for i in '0123456789'|make_list %} 遍历所有 10 个,而不是跳过 0。
          • 非常聪明。那么列表理解呢?有点去掉了hackishness,但使用了相同的想法 x = 5, y=[i for i in range(x)] context={'iterateover':y}
          • @Dave_750 context={'iterateover': range(x)} 也能正常工作
          • 用'rjust'生成任意长度的字符串{% for i in "x"|rjust:"100" %}
          【解决方案9】:

          你可以通过:

          { 'n' : range(n) }

          使用模板:

          {% for i in n %} ... {% endfor %}

          【讨论】:

          • 可读且简单,如果您是下一个维护代码的人,则易于理解发生了什么
          【解决方案10】:

          这本质上需要一个range 函数。为此提出了 Django 功能票 (https://code.djangoproject.com/ticket/13088),但由于“无法修复”而关闭,并附有以下评论。

          我对这个想法的印象是,它试图导致在模板中编程。如果你有一个需要渲染的选项列表,它们应该在视图中计算,而不是在模板中。如果这就像一系列值一样简单,那就这样吧。

          他们有一个很好的观点 - 模板应该是视图的非常简单的表示。您应该在视图中创建有限的所需数据并在上下文中传递给模板。

          【讨论】:

          • 视图应该用于数据,模板应该用于演示。视图不应该要求了解模板的内容,特别是范围。 Django 忽略这些功能请求的原因是完全垃圾。
          【解决方案11】:

          您可以使用: {% with ''|center: i as range %}

          【讨论】:

          • 你能提供一个例子/解释这是如何工作的吗?
          【解决方案12】:

          我在这个问题上非常努力,我在这里找到了最好的答案: (来自how to loop 7 times in the django templates)

          您甚至可以访问 idx!

          views.py:

          context['loop_times'] = range(1, 8)
          

          html:

          {% for i in loop_times %}
                  <option value={{ i }}>{{ i }}</option>
          {% endfor %}
          

          【讨论】:

          • 更具体。我们应该怎么写context['loop_times'] = range(1, 8)。如果可能的话,给出整个代码
          【解决方案13】:

          你可以传递一个绑定

          {'n' : range(n) }
          

          到模板,然后做

          {% for i in n %}
          ...
          {% endfor %}
          

          请注意,您将获得基于 0 的行为 (0, 1, ... n-1)。

          (为兼容 Python3 而更新)

          【讨论】:

          • 在 python 3 中使用range(n),如果我没记错的话,xrange 已被弃用
          • 确实是的。这是我在将应用程序转换到 Python3 时不得不使用的两行代码之一。
          • 2021 年工作!投了赞成票!
          【解决方案14】:

          此方法支持标准range([start,] stop[, step])函数的所有功能

          &lt;app&gt;/templatetags/range.py

          from django import template
          
          register = template.Library()
          
          
          @register.filter(name='range')
          def _range(_min, args=None):
              _max, _step = None, None
              if args:
                  if not isinstance(args, int):
                      _max, _step = map(int, args.split(','))
                  else:
                      _max = args
              args = filter(None, (_min, _max, _step))
              return range(*args)
          

          用法:

          {% load range %}
          
          <p>stop 5
          {% for value in 5|range %}
          {{ value }}
          {% endfor %}
          </p>
          
          <p>start 5 stop 10
          {% for value in 5|range:10 %}
          {{ value }}
          {% endfor %}
          </p>
          
          <p>start 5 stop 10 step 2
          {% for value in 5|range:"10,2" %}
          {{ value }}
          {% endfor %}
          </p>
          

          输出

          <p>stop 5
          0 1 2 3 4
          </p>
          
          <p>start 5 stop 10
          5 6 7 8 9
          </p>
          
          <p>start 5 stop 10 step 2
          5 7 9
          </p>
          

          【讨论】:

          • 您的解决方案不适用于for value in 0|range:"10,2"。你必须改变你的代码如下:args = filter(lambda x: isinstance(x, int) and x &gt;= 0, (_min, _max, _step))
          • @Bedilbek 此代码模仿标准的 python 范围。即使没有明确的 step 参数,它也不支持负范围。 >>> list(range(10,2)) [] >>> list(range(10,2,-1)) [10, 9, 8, 7, 6, 5, 4, 3]
          【解决方案15】:

          可能是这样的?

          {% for i in "x"|rjust:"100" %}
          ...
          {% endfor %}
          

          【讨论】:

          • 工作,但对于另一个出现并看到它的开发人员来说不容易阅读。
          【解决方案16】:
          {% with ''|center:n as range %}
          {% for _ in range %}
              {{ forloop.counter }}
          {% endfor %}
          {% endwith %}
          

          【讨论】:

          • 很好的答案。之所以有效,是因为 center 创建了一个由 n 个空格组成的字符串,然后将其循环。然后忽略每个空格字符,但可以从 forloop.counter(或 forloop.counter0)中找到范围内的当前值。见docs.djangoproject.com/en/dev/ref/templates/builtins/#center
          【解决方案17】:

          您应该在模板中使用“slice”,例如:

          在views.py中

          contexts = {
              'ALL_STORES': Store.objects.all(),
          }
          
          return render_to_response('store_list.html', contexts, RequestContext(request, processors=[custom_processor]))
          

          在 store_list.html 中:

          <ul>
          {% for store in ALL_STORES|slice:":10" %}
              <li class="store_item">{{ store.name }}</li>
          {% endfor %}
          </ul>
          

          【讨论】:

          • 不确定这是否是 OP 想要的,但这正是我想要的。 =)
          【解决方案18】:

          如果数字来自模型,我发现这是模型的一个很好的补丁:

          def iterableQuantity(self):
              return range(self.quantity)
          

          【讨论】:

          • 不知道为什么你会被否决,这是一个有效的答案。与我上面提供的实施适当的过滤器相比,我不喜欢这个解决方案。数据库模型应该保持精简。但它仍然比大多数人接受的答案要好。
          • 我什至不知道……
          • 我迟到了 9 年,但我为你投了赞成票,不用担心。
          【解决方案19】:

          以防万一其他人遇到这个问题……我创建了一个模板标签,可让您创建 range(...): http://www.djangosnippets.org/snippets/1926/

          接受与内置的“范围”相同的参数并创建一个包含 “范围”的结果。 句法: {% mkrange [start,] stop[, step] as context_name %} 例如: {% mkrange 5 10 2 作为 some_range %} {% for i in some_range %} {{ i }}:我想重复的内容\n {% endfor %} 产生: 5:我想重复的东西 7:我想重复的东西 9:我想重复的东西

          【讨论】:

          • -1 支持 Alex Pi 的 sn-p,它增加了对可变参数的支持。
          【解决方案20】:

          您不传递n 本身,而是传递range(n) [包括从0 到n-1 的整数列表],从您的视图到您的模板,在后者中您传递{% for i in therange %}(如果您绝对坚持使用基于 1 而不是正常的基于 0 的索引,您可以在循环体中使用 forloop.counter;-)。

          【讨论】:

            【解决方案21】:

            不幸的是,这是 Django 模板语言中的not supported。 suggestions 中有一个couple,但它们看起来有点复杂。我只想在上下文中放置一个变量:

            ...
            render_to_response('foo.html', {..., 'range': range(10), ...}, ...)
            ...
            

            在模板中:

            {% for i in range %}
                 ...
            {% endfor %}
            

            【讨论】:

            • Django 作者禁止在模板中使用纯 python 的动机似乎与解决没有它所带来的痛苦和浪费的时间相比毫无意义和无关紧要,更不用说需要发明一种全新的语言了当一个非常棒的(python!)已经在那里了!
            • @Bogatyr 如果这就是您想要的,请使用 Jinja2:docs.djangoproject.com/en/1.9/topics/templates/…
            • @Bogatyr 因为显然没有什么不好的事情发生,当您可以在模板中调用clear_full_page_cache() 时(在 php/magento 商店中看到,需要相当长的时间来调试)。最后,让服务器渲染它不是很明智,当客户端可以简单且便宜地完成时,因为没有数据与之关联(否则您只需迭代数据)。
            猜你喜欢
            • 1970-01-01
            • 2021-10-17
            • 2019-05-23
            • 2012-07-13
            • 2012-07-25
            • 2015-03-21
            • 1970-01-01
            相关资源
            最近更新 更多