Numérique pour boucle dans les modèles Django

Comment écrire une boucle numérique for dans un modèle Django? Je veux dire quelque chose comme

for i = 1 to n
187
demandé sur Lev 2009-07-10 08:48:04

16 réponses

j'ai utilisé une technique simple qui fonctionne bien pour les petits cas sans étiquettes spéciales et sans contexte supplémentaire.

{% for i in "xxxxxxxxxxxxxxxxxxxx" %}
    {{ forloop.counter0 }}
{% endfor %}

ajustez la longueur de "xxxxxxxxxxxxxxxxxxxx" selon vos besoins. "xxx" pour faire 3 itérations, etc.

325
répondu Udi 2012-09-05 20:22:35

malheureusement, c'est non pris en charge dans le langage de Django template. Il y a un couple de suggestions , mais ils semblent un peu complexes. Je voudrais juste mettre une variable dans le contexte:

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

et dans le modèle:

{% for i in range %}
     ...
{% endfor %}
90
répondu tghw 2009-07-10 05:00:58
{% with ''|center:n as range %}
{% for _ in range %}
    {{ forloop.counter }}
{% endfor %}
{% endwith %}
80
répondu Tomasz Żyźniewski 2013-01-17 22:12:04

mon point de vue sur cette question, je pense est le plus gentil. Je garde un my_filters.py sur le templatetags répertoire.

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

et vous utilisez comme ceci:

{% load my_filters %}
{% for i in 15|times %}
    <li>Item</li>
{% endfor %}
63
répondu Guillermo Siliceo Trueba 2012-10-09 10:12:15

peut-être comme ça?

{% for i in "x"|rjust:"100" %}
...
{% endfor %}
33
répondu CruelSilence 2014-04-13 21:58:27

vous pouvez passer une reliure de

{'n' : range(n) }

au modèle, puis faire

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

notez que vous obtiendrez un comportement basé sur 0 (0, 1,... n-1).

(mis à jour pour la compatibilité Python3)

30
répondu Dave W. Smith 2016-04-13 00:46:31

vous ne passez pas n lui-même, mais plutôt range(n) [la liste des entiers de 0 à n-1 inclus], de votre point de vue à votre modèle, et dans ce dernier vous faites {% for i in therange %} (si vous insistez absolument sur 1-basé plutôt que le Normal 0-basé l'index, vous pouvez utiliser forloop.counter dans le corps de la boucle; -).

9
répondu Alex Martelli 2009-07-10 05:05:02

juste au cas où quelqu'un d'autre tombe sur cette question... j'ai créé un template tag qui vous permet de créer un 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

9
répondu David Wolever 2010-02-14 22:50:48

Vous devez utiliser " tranche " dans le modèle, un exemple comme ceci:

views.py

contexts = {
    'ALL_STORES': Store.objects.all(),
}

return render_to_response('store_list.html', contexts, RequestContext(request, processors=[custom_processor]))

dans store_list.html:

<ul>
{% for store in ALL_STORES|slice:":10" %}
    <li class="store_item">{{ store.name }}</li>
{% endfor %}
</ul>
6
répondu Vinta 2012-08-15 03:30:23

cette méthode prend en charge toutes les fonctionnalités de la norme range([start,] stop[, step]) fonction

<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)

Utilisation:

{% 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>

sortie

<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>
6
répondu Rebs 2016-02-23 04:52:45

j'ai essayé très fort sur cette question, et je trouve la meilleure réponse ici: (à partir de comment faire une boucle 7 fois dans les modèles django )

vous pouvez même accéder à l'idx!

views.py:

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

html:

{% for i in loop_times %}
        <option value={{ i }}>{{ i }}</option>
{% endfor %}
6
répondu KKlalala 2017-05-23 12:26:37

je vais juste pousser un peu plus loin la réponse populaire et la rendre plus robuste. Cela vous permet de spécifier n'importe quel point de départ, donc 0 ou 1 par exemple. Il utilise également la fonctionnalité de portée de python où la fin est une de moins, de sorte qu'il peut être utilisé directement avec les longueurs de liste par exemple.

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

ensuite, dans votre modèle, il suffit d'inclure le fichier tag template ci-dessus et d'utiliser ce qui suit:

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

Maintenant, vous pouvez faire 1-6 au lieu de seulement 0-6 ou codage dur il. Ajouter une étape nécessiterait une étiquette de modèle, cela devrait couvrir plus de cas d'utilisation donc c'est un pas en avant.

3
répondu Paul Kenjora 2016-09-05 07:20:34

vous pouvez utiliser: {% with ''|center: i as range %}

2
répondu rkoots 2016-09-14 23:14:17

cela nécessite essentiellement une fonction range . Un billet spécial Django a été augmenté ( https://code.djangoproject.com/ticket/13088 ) pour cela, mais fermé comme" ne sera pas fixer " avec le commentaire suivant.

mon impression de cette idée est qu'il essaie de conduire à la programmation dans le modèle. Si vous avez une liste d'options qui doivent être rendus, ils doivent être calculées de la vue, et non pas dans le modèle. Si c'est comme simple comme une plage de valeurs, alors ainsi soit-il.

ils ont un bon point - les gabarits sont censés être des représentations très simples de la vue. Vous devez créer les données requises limitées dans la vue et passer au modèle dans le contexte.

1
répondu Alastair McCormack 2017-02-27 16:27:40

vous pouvez passer:

{'n': range (n) }

pour utiliser le modèle:

{%pour i en n %} ... {% finpour %}

1
répondu rkoots 2018-06-25 10:45:53

si le numéro vient d'un modèle, j'ai trouvé que c'est un bon patch pour le modèle:

def iterableQuantity(self):
    return range(self.quantity)
-2
répondu Alper 2011-03-10 18:45:11