Djangoテンプレートの数値forループ


261

forDjangoテンプレートに数値ループを書き込むにはどうすればよいですか?私のようなものを意味します

for i = 1 to n

回答:


392

私は、特別なタグや追加のコンテキストがなく、小さなケースでうまく機能する単純な手法を使用しました。時々これは重宝します

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

9
FWIW、012 == 12、1と2でのみループします
jason

22
すべての10を超える反復する、0スキップしない| {make_list%「0123456789」でiに対する%}
リック

7
「rjust」を使用して任意の長さの文字列を生成します{% for i in "x"|rjust:"100" %}
アーロン

27
3回目、この答えは悪いです。これは使用しないでください。テンプレートタグを使用して、適切に実行してください。私は答えを言うのが悪いとは思いません。コメントを削除するのに十分な理由です。
Rebs

6
@Rebsこれは何がそんなに悪いのですか?確かにハッキーですが、プロジェクトで小さな範囲を1回ループする必要があるという理由だけでテンプレートタグを追加することも、優れたソリューションではありません。
tobltobs 2017年

114
{% with ''|center:n as range %}
{% for _ in range %}
    {{ forloop.counter }}
{% endfor %}
{% endwith %}

9
すばらしい答えです。センターがn個のスペースの文字列を作成し、その後ループされるため、機能します。各スペース文字は無視されますが、範囲内の現在の値はforloop.counter(またはforloop.counter0)から見つけることができます。docs.djangoproject.com/en/dev/ref/templates/builtins/#center
isedwards

2
正解です。新しいフィルターを作成する必要はありませんでした。
Miguel Ike、

何もする必要はありません。優れたハック
Mohammed Shareef C

106

残念ながら、これはDjangoテンプレート言語ではサポートされていませんいくつか提案がありますが、少し複雑に見えます。私はコンテキストに変数を置くだけです:

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

そしてテンプレートで:

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

13
テンプレートでプレーンpythonを許可しないことに対するDjangoの作者の動機は、完全に素晴らしいもの(python! )すでにそこにあります!
Bogatyr 2016

2
:あなたが欲しいものだ@Bogatyrの場合は、ちょうどJinja2の使用docs.djangoproject.com/en/1.9/topics/templates/...を
tghw

78

この問題についての私の見解は、私は最も素晴らしいと思います。my_filters.pyをtemplatetagsディレクトリに置いています。

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

そして、あなたはこのように使います:

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

1
これは正しい解決策だと思います。行いrange(1, 16)、1から始まる番号を取得していない0
chhantyal

また、templatetagsディレクトリに空のファイル_ init _.pyを作成します。また、これらの行をmy_filters.pyの先頭に追加しますfrom django.template import Library;register = Library()
Ajeeb.KP

2番目のフィルターパラメーターを追加すると、Pythonにフルレンジの関数が組み込まれます。@register.filter(name='range') def filter_range(start, end): return range(start, end)次にとして使用され{% for i in 1|range:6 %}{% endfor %}ます。....以下の完全な答えを参照してください
ポールKenjora

私は(書式設定言い訳)、わずかにこれを変更します:try: return range(number) except: return []。これにより、エラーが発生することはなく、空の配列が返されます(ほとんどのテンプレート関数の動作と同様)。
Tim Tisdall 2017


41

あなたはのバインディングを渡すことができます

{'n' : range(n) }

テンプレートに、次に行います

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

0ベースの動作(0、1、... n-1)になることに注意してください。

(Python3互換性のために更新)


1
使用range(n)のpython 3で、私はそれを正しく覚えていれば、はxrangeはそれに廃止されました
Felício

確かにそう。そして、これは、アプリをPython3に移行するときに偶然に見つけなければならなかった2行のコードの1つでした。
Dave W. Smith

9

あなたはn自分自身を渡しませんがrange(n)、ビューからテンプレートに[0からn-1までの整数のリストが含まれる]と渡します。後者の場合は{% for i in therange %}(通常の0ではなく1ベースを絶対に主張する場合) - forloop.counterループの本体で使用できるベースのインデックス;-)。


9

他の誰かがこの質問に出くわした場合に備えて…を作成できるテンプレートタグを作成しましたrange(...)http : //www.djangosnippets.org/snippets/1926/

組み込みの「範囲」と同じ引数を受け入れ、以下を含むリストを作成します
「範囲」の結果。

構文:
    {%mkrange [start、] stop [、step] as context_name%}

例えば:
    {%mkrange 5 10 2 as some_range%}
    {some_range%のi%for i}
      {{i}}:繰り返したいこと\ n
    {%forfor%}

生成する:
    5:繰り返したいこと 
    7:繰り返したいこと 
    9:繰り返したいこと


1
-1可変引数のサポートを追加するAlex Piのスニペットを支持します。
m000 2012


9

あなたは渡すことができます:

{'n':range(n)}

テンプレートを使用するには:

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


読みやすく、シンプルで、コードを管理している次の人が何をしているのかわかりやすい
rossdavidh

7

次のような例では、テンプレートで「スライス」を使用する必要があります。

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>

1
これがOPが探していたものかどうかはわかりませんが、まさにそれが私が探していたものです。=)
GChorn、2014年

7

このメソッドは、標準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

@Bedilbekこのコードは、標準のPython範囲を模倣しています。明示的なステップパラメーターがない場合でも、負の範囲はサポートされません。>>> list(range(10,2))[] >>> list(range(10,2、-1))[10、9、8、7、6、5、4、3]
反乱

5

私は人気のある答えをもう少し先に進め、より堅牢にします。これにより、任意の開始点を指定できるため、たとえば0または1になります。また、末尾が1つ少ないpythonの範囲機能を使用しているため、リストの長さなどで直接使用できます。

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

次に、テンプレートに上記のテンプレートタグファイルを含めて、以下を使用します。

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

これで、0-6またはハードコーディングする代わりに1-6を実行できます。ステップを追加するには、テンプレートタグが必要です。これにより、より多くのユースケースがカバーされるため、一歩前進です。


これは@ guillermo-siliceo-trueba回答の拡張です。
ポールケンジョラ16

5

これには基本的にrange関数が必要です。このためにDjango機能チケットが生成されました(https://code.djangoproject.com/ticket/13088)が、次のコメントで「修正されない」として閉じられました。

このアイデアの私の印象は、それがテンプレートでのプログラミングにつながることを試みているということです。レンダリングする必要があるオプションのリストがある場合は、テンプレートではなくビューで計算する必要があります。それが値の範囲と同じくらい単純であれば、それもそうです。

彼らは良い点を持っています-テンプレートはビューの非常に単純な表現であることになっています。ビューで限られた必要なデータを作成し、コンテキストでテンプレートに渡す必要があります。


6
ビューはデータ用であり、テンプレートはプレゼンテーション用である必要があります。ビューには、テンプレートの内容、特に範囲の知識は必要ありません。Djangoがこれらの機能リクエストを無視する理由はまったくのごみです。
Rebs

3

以下を使用できます。 {% with ''|center: i as range %}


1
これがどのように機能するかの例/説明を提供できますか?
Rebs

1

番号がモデルからのものである場合、これはモデルに対する素晴らしいパッチであることがわかりました。

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

2
なぜあなたが反対票を投じられるのかわからない、それは有効な答えです。上記で提供した適切なフィルターの実装と比較して、私はこのソリューションが好きではありません。DBモデルは無駄のない状態に保つ必要があります。しかし、それはまだ大多数が受け入れた答えよりも優れています。
Rebs

私も知りません…
アルパー

私は9年遅すぎますが、あなたの家族に賛成票を投じました。心配することすらありません。
Sahil

1

単純な答えを探している、値の量を表示する必要があるだけの場合、たとえば、100の投稿から3つを追加して{% for post in posts|slice:"3" %}、通常のようにループすると、3つの投稿のみが追加されます。


-5
{% for i in range(10) %}
   {{ i }}

{% endfor %}

このコードは質問に答えることがありますが、このコードが質問に答える理由や方法に関する追加のコンテキストを提供すると、長期的な価値が向上します。
xiawi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.