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?

underdoeg
la source
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 %}
Burhan Khalid
la source
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' '' '' '' %}">
mipadi
la source
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 %}
à partir de 16
la source
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