Module% dans le modèle Django


121

Je cherche un moyen d'utiliser quelque chose comme l'opérateur modulus dans django. Ce que j'essaie de faire, c'est d'ajouter un nom de classe à chaque quatrième élément d'une boucle.

Avec module, cela ressemblerait à ceci:

{% for p in posts %}
    <div class="post width1 height2 column {% if forloop.counter0 % 4 == 0 %}first{% endif %}}">
        <div class="preview">

        </div>
        <div class="overlay">

        </div>
        <h2>p.title</h2>
    </div>
{% endfor %}

Bien sûr, cela ne fonctionne pas car% est un caractère réservé. Y a-t-un autre moyen de faire ça?


Avez-vous même essayé? Django fournit l' templatetagétiquette, mais qui couvre {%, %}etc. (non %).
Platinum Azure

4
oui, je l'ai essayé, mais j'obtiens l'erreur suivante: Impossible d'analyser le reste: '%' de '%' Je suppose que c'est parce qu'il ne sait pas comment parer le moduleur. L'opérateur n'est pas non plus répertorié sur la documentation docs.djangoproject.com/en/dev/ref/templates/builtins/…
underdoeg

Réponses:


210

Vous avez besoin de divisibleby , un filtre django intégré.

{% for p in posts %}
    <div class="post width1 height2 column {% if forloop.counter0|divisibleby:4 %}first{% endif %}">
        <div class="preview">

        </div>
        <div class="overlay">

        </div>
        <h2>p.title</h2>
    </div>
{% endfor %}

1
ah oui, c'est exactement ça. en utilisant le cycle maintenant, mais bon pour référence future. Je ne voudrais pas utiliser le cycle avec le moduleur 100 ou quelque chose du genre :) En fait, je vais marquer cette réponse comme la bonne. car il se concentre sur Modulor et non pas une solution ...
underdoeg

15

Vous ne pouvez pas utiliser l'opérateur modulus dans les balises de gabarit Django, mais il serait assez facile d'écrire un filtre pour le faire. Quelque chose comme ça devrait fonctionner:

@register.filter
def modulo(num, val):
    return num % val

Puis:

{% ifequal forloop.counter0|modulo:4 0 %}

Vous pouvez même faire quelque chose comme ça à la place:

@register.filter
def modulo(num, val):
    return num % val == 0

Puis:

{% if forloop.counter0|modulo:4 %}

Ou vous pouvez utiliser la cyclebalise:

<div class="post width1 height2 column {% cycle 'first' '' '' '' %}">


12

Exemple de lignes et de colonnes Bootstrap. Nouvelle ligne tous les 4 éléments. Fermez également la dernière ligne même s'il y a moins de 4 éléments.

myapp / templatetags / my_tags.py

from django import template

register = template.Library()

@register.filter
def modulo(num, val):
    return num % val

modèle html

{% load my_tags %}

{% for item in all_items %} 
    {% if forloop.counter|modulo:4 == 1 %}
        <div class="row">
    {% endif %}

        <div class="col-sm-3">
            {{ item }}
        </div>

    {% if forloop.last or forloop.counter|modulo:4 == 0 %}
        </div>
    {% endif %}

{% endfor %}

2
C'est la meilleure réponse car elle décrit le répertoire nécessaire à créer et décrit également la nécessité de charger le modèle personnalisé dans le modèle html. Je vous remercie.
truthadjustr
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.