% De módulo en la plantilla de Django

121

Estoy buscando una forma de usar algo como el operador de módulo en django. Lo que estoy tratando de hacer es agregar un nombre de clase a cada cuarto elemento en un ciclo.

Con módulo se vería así:

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

Por supuesto, esto no funciona porque% es un carácter reservado. Hay alguna otra manera de hacer esto?

desvalido
fuente
¿Lo intentaste siquiera? Django proporciona la templatetagetiqueta, pero que las cubiertas {%, %}, etc. (no %).
Platinum Azure
4
sí, lo intenté, pero aparece el siguiente error: No se pudo analizar el resto: '%' de '%' Supongo que es porque no sabe cómo detener el modulor. El operador tampoco aparece en los documentos docs.djangoproject.com/en/dev/ref/templates/builtins/…
underdoeg

Respuestas:

210

Necesita divisibleby , un filtro django integrado.

{% 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
fuente
1
ah sí, eso es exactamente. usando el ciclo ahora, pero bueno para referencia futura. No quisiera usar el ciclo con modulor 100 o algo así :) En realidad, voy a marcar esta respuesta como la correcta. porque se centra en modulor y no en una solución ...
underdoeg
15

No puede usar el operador de módulo en las etiquetas de plantilla de Django, pero sería bastante fácil escribir un filtro para hacerlo. Algo como esto debería funcionar:

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

Y entonces:

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

Incluso podrías hacer algo como esto, en su lugar:

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

Y entonces:

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

O podrías usar la cycleetiqueta:

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

Ejemplo de filas y columnas de Bootstrap. Fila nueva cada 4 elementos. También cierre la última fila incluso si hay menos de 4 elementos.

myapp / templatetags / my_tags.py

from django import template

register = template.Library()

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

plantilla 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 %}
ab 16
fuente
2
Esta es la mejor respuesta porque describe qué directorio necesario se creará y describe la necesidad de cargar la plantilla personalizada en la plantilla html también. Gracias.
truthadjustr