Often we need to do alternate things in every steps of a django template for loop while doing things in a loop in a django template. For example, let’s say you want to create a widget similar to the following image

widget – to show various job types

In this example, The Job Type widget shows a multi-colored checkbox which shows six colors in total. If more than six items in the list then it will cycle through the colors. Thanks to django’s powerful DTL and jinja2 template engine we can accomplish this in multiple ways. Let’s explore a few possible solutions:

Using forloop.counter & divisibleby

<div class="widget">
        <h3 class="sb-title open">{% trans "Job Type" %}</h3>
        <div class="jobtype_widget">
            <div class="simple-checkbox scrollbar">
                {% for job_type in job_types %}
                 {% if forloop.counter|divisibleby:5 %}  
                <p class="red"><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p>
                 {% elif forloop.counter|divisibleby:4 %}  
                <p class="pink"><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p> 
                 {% if forloop.counter|divisibleby:3 %}  
                <p class="light-green"><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p>
                  {% elif forloop.counter|divisibleby:2 %}  
                <p class="green"><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p>
                  {% elif forloop.counter|divisibleby:1 %}  
                <p class="cyan"><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p>
                 {% endif %}
                {% endfor %}
            </div>
        </div>
</div>
Ugly but it works as expected.

Notice, how we are taking advantage of django’s forloop.counter and the divisibleby tags to make sure in each loop we get an unique and different color cycled in a sequence from red, purple, pink…cyan, red, purple, pink …cyan and so on.
There are some problems though. The above code is a nightmare to maintain and has a lot of unnecessary repetition in it. Now take a look at the next example

Using Cycle

<div class="widget">
        <h3 class="sb-title open">{% trans "Job Type" %}</h3>
        <div class="jobtype_widget">
            <div class="simple-checkbox scrollbar">
                {% for job_type in job_types %}
                <p class={% cycle "red" "purple" "pink" "light-green" "green" "cyan" %}><input type="checkbox" name="job_type" id="job-type-id-{{ job_type.id }}" value="{{ job_type.id }}"><label for="job-type-id-{{ job_type.id }}">{{ job_type.title }}</label></p>
                {% endfor %}
            </div>
        </div>
</div>

It sure looks cleaner than the previous one isn’t it? The magic here is the tag cycle. It will cycle through the given list of strings as long as the loop continues. Read more about template tags and filter here

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.