Jawaban:
Saya telah menggunakan teknik sederhana yang bekerja dengan baik untuk kasus-kasus kecil tanpa tag khusus dan tanpa konteks tambahan. Terkadang ini berguna
{% for i in '0123456789'|make_list %}
{{ forloop.counter }}
{% endfor %}
{% for i in "x"|rjust:"100" %}
{% with ''|center:n as range %}
{% for _ in range %}
{{ forloop.counter }}
{% endfor %}
{% endwith %}
Sayangnya, itu tidak didukung dalam bahasa template Django. Ada beberapa dari saran , tetapi mereka tampak sedikit rumit. Saya hanya akan meletakkan variabel dalam konteks:
...
render_to_response('foo.html', {..., 'range': range(10), ...}, ...)
...
dan di templat:
{% for i in range %}
...
{% endfor %}
Pandangan saya tentang masalah ini, saya pikir adalah yang terbaik. Saya menyimpan my_filters.py di direktori templatetags.
@register.filter(name='times')
def times(number):
return range(number)
Dan Anda akan menggunakan seperti ini:
{% load my_filters %}
{% for i in 15|times %}
<li>Item</li>
{% endfor %}
range(1, 16)
untuk mendapatkan angka mulai dari 1, bukan 0.
from django.template import Library;register = Library()
@register.filter(name='range') def filter_range(start, end): return range(start, end)
Kemudian akan digunakan sebagai {% for i in 1|range:6 %}{% endfor %}
. Lihat jawaban lengkap di bawah ini ....
try: return range(number) except: return []
. Dengan cara itu tidak pernah memunculkan kesalahan dan mengembalikan array kosong (mirip dengan cara sebagian besar fungsi templat bekerja).
Mungkin seperti ini
{% for i in "x"|rjust:"100" %}
...
{% endfor %}
Anda dapat melewati pengikatan
{'n' : range(n) }
ke template, lalu lakukan
{% for i in n %}
...
{% endfor %}
Perhatikan bahwa Anda akan mendapatkan perilaku berbasis 0 (0, 1, ... n-1).
(Diperbarui untuk kompatibilitas Python3)
range(n)
dalam python 3, jika saya mengingatnya dengan benar, xrange sudah tidak digunakan lagi
Anda tidak lulus n
sendiri, melainkan range(n)
[daftar bilangan bulat dari 0 hingga n-1 disertakan], dari tampilan Anda ke template Anda, dan yang terakhir Anda lakukan {% for i in therange %}
(jika Anda benar-benar bersikeras berbasis 1 daripada yang normal 0 Indeks berbasis yang dapat Anda gunakan forloop.counter
dalam tubuh loop ;-).
Hanya memetikan orang lain menemukan pertanyaan ini ... Saya telah membuat tag template yang memungkinkan Anda membuat range(...)
: http://www.djangosnippets.org/snippets/1926/
Menerima argumen yang sama dengan builtin 'range' dan membuat daftar yang berisi hasil 'rentang'. Sintaksis: {% mkrange [start,] stop [, step] sebagai context_name%} Sebagai contoh: {% mkrange 5 10 2 sebagai some_range%} {% untuk saya di some_range%} {{i}}: Sesuatu yang ingin saya ulangi \ n {% endfor%} Menghasilkan: 5: Sesuatu yang ingin aku ulangi 7: Sesuatu yang ingin saya ulangi 9: Sesuatu yang ingin saya ulangi
Saya berusaha sangat keras pada pertanyaan ini, dan saya menemukan jawaban terbaik di sini: (dari cara loop 7 kali dalam template Django )
Anda bahkan dapat mengakses idx!
views.py:
context['loop_times'] = range(1, 8)
html:
{% for i in loop_times %}
<option value={{ i }}>{{ i }}</option>
{% endfor %}
Anda dapat lulus:
{'n': range (n)}
Untuk menggunakan templat:
{% untuk i di n%} ... {% endfor%}
Anda harus menggunakan " slice " pada template, contohnya seperti ini:
di views.py
contexts = {
'ALL_STORES': Store.objects.all(),
}
return render_to_response('store_list.html', contexts, RequestContext(request, processors=[custom_processor]))
di store_list.html:
<ul>
{% for store in ALL_STORES|slice:":10" %}
<li class="store_item">{{ store.name }}</li>
{% endfor %}
</ul>
Metode ini mendukung semua fungsi dari range([start,] stop[, step])
fungsi standar
<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)
Pemakaian:
{% 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>
Keluaran
<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"
. Anda harus mengubah kode Anda sebagai berikut:args = filter(lambda x: isinstance(x, int) and x >= 0, (_min, _max, _step))
Saya hanya mengambil jawaban populer sedikit lebih jauh dan membuatnya lebih kuat. Ini memungkinkan Anda menentukan titik awal, jadi 0 atau 1 misalnya. Ini juga menggunakan fitur jangkauan python di mana ujungnya satu kurang sehingga dapat digunakan secara langsung dengan panjang daftar misalnya.
@register.filter(name='range')
def filter_range(start, end):
return range(start, end)
Kemudian dalam template Anda cukup sertakan file tag template di atas dan gunakan yang berikut ini:
{% for c in 1|range:6 %}
{{ c }}
{% endfor %}
Sekarang Anda dapat melakukan 1-6 alih-alih hanya 0-6 atau mengkodekannya dengan keras. Menambahkan langkah akan membutuhkan tag templat, ini harus mencakup lebih banyak kasus penggunaan jadi ini adalah langkah maju.
Ini pada dasarnya membutuhkan suatu range
fungsi. Tiket fitur Django dinaikkan ( https://code.djangoproject.com/ticket/13088 ) untuk ini tetapi ditutup sebagai "tidak akan diperbaiki" dengan komentar berikut.
Kesan saya terhadap ide ini adalah bahwa ia mencoba mengarah ke pemrograman dalam template. Jika Anda memiliki daftar opsi yang perlu dirender, mereka harus dihitung dalam tampilan, bukan dalam template. Jika itu sesederhana rentang nilai, maka jadilah itu.
Mereka memiliki poin yang bagus - Template seharusnya merupakan representasi tampilan yang sangat sederhana. Anda harus membuat data yang diperlukan terbatas dalam tampilan dan meneruskan ke templat dalam konteks.
Jika nomor tersebut berasal dari model, saya menemukan ini sebagai tambalan yang bagus untuk model:
def iterableQuantity(self):
return range(self.quantity)
Bagi mereka yang mencari jawaban sederhana, hanya perlu menampilkan sejumlah nilai, katakanlah 3 dari 100 posting misalnya cukup tambahkan {% for post in posts|slice:"3" %}
dan putar secara normal dan hanya 3 posting yang akan ditambahkan.
{% for i in range(10) %}
{{ i }}
{% endfor %}