53

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?

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
Sammy
  • 557
  • 1
  • 5
  • 6
  • 1
    I tried this code on a list objects with only one item, and the content for both sections is displaying as expected. – Brandon Taylor Aug 09 '11 at 15:46
  • 1
    This could still depend on django versions I think you should mention the version of django you are using. – dusual Aug 10 '11 at 11:50

4 Answers4

43

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
Mahendra Yadav
  • 535
  • 6
  • 16
newmaniese
  • 773
  • 7
  • 7
10

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 %}
Christopher
  • 169
  • 2
  • 6
1

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 %}
Alkindus
  • 2,064
  • 2
  • 16
  • 16
0

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>
LucianoBAF
  • 189
  • 2
  • 6