[Fixed]-Django template {%for%} tag add li every 4th element

62👍

The following should solve your problem, using built-in template tags :

<ul>
    <li>
    {% for obj in objects %}
        <a>{{ obj }}</a>

    {# if the the forloop counter is divisible by 4, close the <li> tag and open a new one #}
    {% if forloop.counter|divisibleby:4 %}
    </li>
    <li>
    {% endif %}

    {% endfor %}
    </li>
</ul>

18👍

You can use the divisibleby tag as mentioned before, but for template clearing purposes I usually prefer a helper function that returns a generator:

def grouped(l, n):
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

example simplistic view:

from app.helpers import grouped

def foo(request):
    context['object_list'] = grouped(Bar.objects.all(), 4)
    return render_to_response('index.html', context)

example template:

{% for group in object_list %}
   <ul>
        {% for object in group %}
            <li>{{ object }}</li>
        {% endfor %}
   </ul>
{% endfor %}

3👍

you can use divisibleby built-in filter, here is link to django documentation

so something like this would work

{% if value|divisibleby 4 %}
#your conditional code
{% endif %}

2👍

if you want to work it with checking first forloop and last forloop you could use this :

<ul>
{% for obj in objects %}
{% if forloop.first %}
    <li>
{% endif %}
        <a>{{obj}}</a>
{% if forloop.counter|divisibleby:4 and not forloop.first %}
    </li>
    <li>
{% endif %}
{% if forloop.last %}
    </li>
{% endif %}
{% endfor %}
</ul>

1👍

I personally would consider to separate the elements in the view before passing them to the template and then using nested for loops. Except this you really only have the filter or templatetag option as Vaibhav Mishra mentioned.

Leave a comment