Risposte:
Ho usato una tecnica semplice che funziona bene per casi piccoli senza tag speciali e senza contesto aggiuntivo. A volte questo è utile
{% 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 %}
Sfortunatamente, questo non è supportato nel linguaggio dei template di Django. Ci sono un paio di suggerimenti , ma sembrano un po 'complessi. Vorrei solo inserire una variabile nel contesto:
...
render_to_response('foo.html', {..., 'range': range(10), ...}, ...)
...
e nel modello:
{% for i in range %}
...
{% endfor %}
La mia opinione su questo problema, penso che sia il migliore. Tengo un my_filters.py nella directory templatetags.
@register.filter(name='times')
def times(number):
return range(number)
E useresti così:
{% load my_filters %}
{% for i in 15|times %}
<li>Item</li>
{% endfor %}
range(1, 16)
per ottenere numeri a partire da 1, non da 0.
from django.template import Library;register = Library()
@register.filter(name='range') def filter_range(start, end): return range(start, end)
Quindi si abitua come {% for i in 1|range:6 %}{% endfor %}
. Vedi la risposta completa di seguito ....
try: return range(number) except: return []
. In questo modo non genera mai un errore e restituisce un array vuoto (simile a come funzionano la maggior parte delle funzioni del modello).
Forse così?
{% for i in "x"|rjust:"100" %}
...
{% endfor %}
Puoi passare un'associazione di
{'n' : range(n) }
al modello, quindi esegui
{% for i in n %}
...
{% endfor %}
Nota che otterrai un comportamento basato su 0 (0, 1, ... n-1).
(Aggiornato per la compatibilità con Python3)
range(n)
in Python 3, se lo ricordo correttamente, xrange è stato deprecato su di esso
Non passi da n
solo, ma piuttosto range(n)
[l'elenco di numeri interi compresi tra 0 e n-1], dalla tua vista al tuo modello, e in quest'ultimo {% for i in therange %}
caso (se insisti assolutamente su 1 basato anziché sul normale 0 basato sull'indice che puoi usare forloop.counter
nel corpo del loop ;-).
Nel caso in cui qualcuno si imbattesse in questa domanda ... Ho creato un tag modello che ti consente di creare un range(...)
: http://www.djangosnippets.org/snippets/1926/
Accetta gli stessi argomenti del 'range' incorporato e crea un elenco contenente il risultato di "range". Sintassi: {% mkrange [start,] stop [, step] come context_name%} Per esempio: {% mkrange 5 10 2 as some_range%} {% for i in some_range%} {{i}}: Qualcosa che voglio ripetere \ n {% endfor%} produce: 5: Qualcosa che voglio ripetere 7: Qualcosa che voglio ripetere 9: Qualcosa che voglio ripetere
Ho provato molto su questa domanda e trovo la risposta migliore qui: (da come eseguire 7 cicli nei template di django )
Puoi persino accedere a idx!
views.py:
context['loop_times'] = range(1, 8)
html:
{% for i in loop_times %}
<option value={{ i }}>{{ i }}</option>
{% endfor %}
Puoi passare:
{'n': range (n)}
Per utilizzare il modello:
{% for i in n%} ... {% endfor%}
Dovresti usare " slice " nel modello, un esempio come questo:
in views.py
contexts = {
'ALL_STORES': Store.objects.all(),
}
return render_to_response('store_list.html', contexts, RequestContext(request, processors=[custom_processor]))
in store_list.html:
<ul>
{% for store in ALL_STORES|slice:":10" %}
<li class="store_item">{{ store.name }}</li>
{% endfor %}
</ul>
Questo metodo supporta tutte le funzionalità della range([start,] stop[, step])
funzione standard
<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)
Uso:
{% 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>
Produzione
<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"
. Devi cambiare il tuo codice come segue:args = filter(lambda x: isinstance(x, int) and x >= 0, (_min, _max, _step))
Sto solo prendendo un po 'più in là la risposta popolare e la sto rendendo più solida. Ciò consente di specificare qualsiasi punto iniziale, ad esempio 0 o 1. Utilizza anche la funzione di intervallo di Python in cui la fine è una in meno, quindi può essere utilizzata direttamente con lunghezze di elenco, ad esempio.
@register.filter(name='range')
def filter_range(start, end):
return range(start, end)
Quindi nel modello è sufficiente includere il file tag modello sopra riportato e utilizzare quanto segue:
{% for c in 1|range:6 %}
{{ c }}
{% endfor %}
Ora puoi fare 1-6 invece di solo 0-6 o codificarlo a fondo. L'aggiunta di un passaggio richiederebbe un tag modello, questo dovrebbe coprire più casi d'uso quindi è un passo avanti.
Ciò richiede essenzialmente una range
funzione. A questo scopo è stato generato un ticket funzione Django ( https://code.djangoproject.com/ticket/13088 ) ma chiuso come "non risolto" con il seguente commento.
La mia impressione di questa idea è che sta cercando di condurre alla programmazione nel modello. Se si dispone di un elenco di opzioni che devono essere visualizzate, dovrebbero essere calcolate nella vista, non nel modello. Se è semplice come un intervallo di valori, allora sia così.
Hanno un buon punto: i modelli dovrebbero essere rappresentazioni molto semplici della vista. È necessario creare i dati richiesti limitati nella vista e passare al modello nel contesto.
Se il numero proviene da un modello, ho scoperto che questa è una bella patch per il modello:
def iterableQuantity(self):
return range(self.quantity)
Per coloro che cercano una risposta semplice, hanno solo bisogno di visualizzare una quantità di valori, diciamo che 3 su 100 post, ad esempio, basta aggiungerlo {% for post in posts|slice:"3" %}
e collegarlo normalmente e verranno aggiunti solo 3 post.
{% for i in range(10) %}
{{ i }}
{% endfor %}