ChatGPT解决这个技术问题 Extra ChatGPT

Modulus % in Django template

I'm looking for a way to use something like the modulus operator in django. What I am trying to do is to add a classname to every fourth element in a loop.

With modulus it would look like this:

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

Of course this doesn't work because % is a reserved character. Is there any other way to do this?

Did you even try it? Django provides the templatetag tag, but that covers {%, %}, etc. (not %).
yes, I tried it, but I get the following error: Could not parse the remainder: '%' from '%' I assume it is because it doesn't know how to pare the modulor. The operator is also not listed on the docs docs.djangoproject.com/en/dev/ref/templates/builtins/…

B
Burhan Khalid

You need divisibleby, a built-in django filter.

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

ah yes, that's exactly it. using cycle now, but good for future reference. I wouldn't want to use cycle with modulor 100 or something :) Actually I am goint to mark this answer as the correct one. because it focuses on modulor and not a workaround...
m
mipadi

You can't use the modulus operator in Django template tags, but it would be easy enough to write a filter to do so. Something like this should work:

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

And then:

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

You could even do something like this, instead:

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

And then:

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

Or you could use the cycle tag:

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

a
ab 16

Bootstrap rows and columns example. New row every 4 items. Also close last row even if there are less than 4 items.

myapp/templatetags/my_tags.py

from django import template

register = template.Library()

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

html template

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

This is the better answer because it describes what needed directory is to be created and it describes the need to load the custom template in the template html also. Thank you.
So if I have the same setup as this, moved my applet into the installed apps of my settings.py, have reset my server, can access the template tag from the shell, have loaded the tag in the template like you have, why can't I use modulo!?!? I've followed the Django tutorial down to a t.
s
spacediver

It sounds like you should just use the cycle tag. Built-in template tags