% De módulo no modelo do Django

120

Estou procurando uma maneira de usar algo como o operador de módulo no django. O que estou tentando fazer é adicionar um nome de classe a cada quarto elemento em um loop.

Com o módulo, ficaria assim:

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

Claro que isso não funciona porque% é um caractere reservado. Existe alguma outra maneira de fazer isso?

underdoeg
fonte
Você tentou mesmo? Django fornece a templatetagtag, mas que cobre {%, %}etc. (não %).
Platinum Azure
4
sim, tentei, mas recebo o seguinte erro: Não foi possível analisar o restante: '%' from '%' Suponho que seja porque não sabe como analisar o modulador. O operador também não está listado nos documentos docs.djangoproject.com/en/dev/ref/templates/builtins/…
underdoeg

Respostas:

210

Você precisa divisível por um filtro django embutido.

{% 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
fonte
1
ah sim, é exatamente isso. usando o ciclo agora, mas bom para referência futura. Eu não gostaria de usar o ciclo com o módulo 100 ou algo assim :) Na verdade, eu vou marcar essa resposta como correta. porque se concentra em modulor e não uma solução alternativa ...
underdoeg
15

Você não pode usar o operador modulus nas tags de modelo do Django, mas seria fácil escrever um filtro para isso. Algo assim deve funcionar:

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

E depois:

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

Você poderia até fazer algo assim:

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

E depois:

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

Ou você pode usar a cycletag:

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

Exemplo de linhas e colunas de inicialização. Nova linha a cada 4 itens. Feche também a última linha, mesmo que haja menos de 4 itens.

myapp / templatetags / my_tags.py

from django import template

register = template.Library()

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

modelo 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
fonte
2
Essa é a melhor resposta, pois descreve o diretório necessário a ser criado e também descreve a necessidade de carregar o modelo personalizado no html do modelo. Obrigado.
truthadjustr