Django templates: forloop.first and forloop.last

Question:

I have the following code in my template:

{% for f in friendslist %}

        {% if forloop.first %}
            // display something                            
        {% endif %}

        // display stuff

        {% if forloop.last %}
            // display something
        {% endif %}

{% endfor %}

It works as expected when there is more than one item in the friendslist. But if there is just 1 item, then the content inside the forloop.last
conditional does not display.

I guess this is because the loop in that case is the first, but I mean it’s also the last right? So why dosn’t both contents inside first and last
conditional show?

Asked By: Sammy

||

Answers:

In my code they both execute if there is only one element in friendslist. Here is a test you can run in the shell where maybe you can figure out what isn’t working:

$ ./manage.py shell

>>> from django import template
>>> t = template.Template("""{% for f in friendslist %}
                         {% if forloop.first %}
                             First of the loop                            
                         {% endif %}
                         {{ f }}
                         {% if forloop.last %}
                             Last of the loop
                         {% endif %}
                 {% endfor %}""")

>>> c = template.Context({'friendslist' : ['one element',]})
>>> t.render(c)


                        First of the loop

                    one element

                         Last of the loop
Answered By: newmaniese

couldn’t you just use an “or” tag like {% if forloop.last or friendlist.count == 1 %}

            {% for f in friendslist %}

                    {% if forloop.first %}
                        // display something                            
                    {% endif %}

                    // display stuff

                    {% if forloop.last or friendlist.count == 1 %}
                        // display something
                    {% endif %}

            {% endfor %}
Answered By: Christopher

You can also use ”not” in template to solve this. It works even there is just an item in the list.

       {% for friend in friendslist %}

                {% if not forloop.last %}
                    // display something                            
                {% endif %}

                {% if forloop.last %}
                    // display something
                {% endif %}
        {% endfor %}
Answered By: Alkindus

Exemplifying the accepted answer for when you need to access a nested json that contains arrays of jsons, and get only the first element.

In the example below, in regards to users’ addresses, I want to show only the phone number of the first phone registered in the user profile.

Example users json that will be passed to the HTML template

{
    "name": "user1",
    "birthdate": "date1",
    "phones": [
        {
            "number": "111111111",
            "type": "type1"
        },
        {
            "number": "222222222",
            "type": "type2"
        }
    ],
}

HTML file to render this example in a table, using Jinja:

<table id="users_table" class="table table-hover table-sm">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Username</th>
        <th scope="col">Birthdate</th>
        <th scope="col">Phone</th>
      </tr>
    </thead>
    <tbody>
      {% for user in users %}
      <tr>
        <th scope="row">{{ forloop.counter }}</th>
        <td>{{ user.name }}</td>
        <td>{{ user.birthdate }}</td>
        {% for phone in user.phones %}
          {% if forloop.first %}
            <td> {{ phone.number }}</td>                      
          {% endif %}
        {% endfor %}
      </tr>
    </tbody>
</table>
Answered By: LucianoBAF
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.