ChatGPT解决这个技术问题 Extra ChatGPT

Django模板中的数字for循环

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

for i = 1 to n

a
alias51

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

{% 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" %} 生成任意长度的字符串
T
Tomasz Żyźniewski
{% 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
这应该被标记为接受的答案 - 方式更加动态。
t
tghw

不幸的是,这是 Django 模板语言中的 not supportedsuggestions 中有 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 商店中看到,需要相当长的时间进行调试)。最后,让服务器渲染它不是很明智,当客户端可以轻松和便宜地完成它,因为没有数据与之关联(否则你只是迭代数据)。
r
radtek

我对这个问题的看法,我认为是最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 解决方案,这在我看来是最好的
D
Dave W. Smith

你可以通过一个绑定

{'n' : range(n) }

到模板,然后做

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

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

(针对 Python3 兼容性进行了更新)


在 python 3 中使用 range(n),如果我没记错的话,不推荐使用 xrange
完全同意。这是我在将应用程序转换到 Python3 时不得不使用的两行代码之一。
2021年工作!投票赞成!
P
Przemysław Pietrzkiewicz

也许像这样?

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

对于出现并看到它的另一个开发人员来说,工作但不容易阅读。
a
ajinzrathod

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

@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 答案的扩展。
很好的答案,你节省了我的时间
这是完美的答案
r
rkoots

你可以通过:

{'n':范围(n)}

使用模板:

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


如果您是下一个维护代码的人,则可读且简单,易于理解正在发生的事情
C
Community

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

您甚至可以访问 idx!

视图.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)。如果可能的话,给出整个代码
A
Alex Martelli

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


D
David Wolever

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

Accepts the same arguments as the 'range' builtin and creates a list containing
the result of 'range'.

Syntax:
    {% mkrange [start,] stop[, step] as context_name %}

For example:
    {% mkrange 5 10 2 as some_range %}
    {% for i in some_range %}
      {{ i }}: Something I want to repeat\n
    {% endfor %}

Produces:
    5: Something I want to repeat 
    7: Something I want to repeat 
    9: Something I want to repeat

-1 支持 Alex Pi 的片段,它增加了对变量参数的支持。
V
Vinta

您应该在模板中使用“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 想要的,但这正是我想要的。 =)
R
Rebs

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

<app>/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 >= 0, (_min, _max, _step))
@Bedilbek 此代码模仿标准的python 范围。即使没有明确的 step 参数,它也不支持负范围。 >>> 列表(范围(10,2)) [] >>> 列表(范围(10,2,-1)) [10, 9, 8, 7, 6, 5, 4, 3]
A
Alastair McCormack

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

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

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


视图应该用于数据,模板应该用于演示。视图不应该要求了解模板的内容,特别是范围。 Django 忽略这些功能请求的原因完全是垃圾。
这实际上很难说这是否是一个好点。模板不应该“承载编程”,但他们今天这样做,使用 for 循环等......实际上,今天的解决方案是添加标签,提供语法支持以允许在模板中调用方法,而默认标签不是会改变很多
J
Jan Kyu Peblik
{% for _ in ''|center:13 %}
    {{ forloop.counter }}
{% endfor %}

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

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

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

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

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


你能提供一个例子/解释这是如何工作的吗?
E
Elias Prado

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


D
Darwin

这显示了 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 %}

S
Srishti Ahuja

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

context['range']= range(n)

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

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

M
Muhammad Abdullah
{% for i in range(10) %}
   {{ i }}

{% endfor %}

虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
无法解析余数:来自 range(10)(10)
您不能在 django 模板中使用 range() 函数。但是您可以使用过滤器来克服这个问题