Search code examples
pythonflaskjinja2

loop.nextitem doesn't work with current value from data


I need to compare postback.campaign_id with the value of the next item. If it's similar, then, I don't print nothing, if not, then, print my row.

But, this code outputs everything.

<table>
    <tr>
        <td class="expand expand-campaign"><a>Test</a></td>
        <td>{{ account_id }}</td>
    </tr>
    {% for postback in postbacks %}
        {% if loop.nextitem is defined and postback.campaign_id != loop.nextitem[0] %}
        <tr>
            <td></td><td></td>
            <td><input type="checkbox"></td>
            <td class="expand expand-site"><a>{{ postback.campaign_id }}</a></td>
        </tr>
      {% endif %}
    {% endfor %}
</table>

Solution

  • The loop.nextitem contains the whole variable in your next item. So, if it is a dictionary or object, like in your case, you can access its properties like the current object under loop.

    In your case that would mean:

    postback.campaign_id != loop.nextitem.campaign_id
    

    You also have the issue that your last item will always be skipped by the condition loop.nextitem is defined. Since you are going to always print the last item of a streak of similar items, you can perfectly do:

    {% if loop.nextitem is undefined 
         or postback.campaign_id != loop.nextitem.campaign_id 
    %}
    

    Also note that, there is a loop.changed() construct in Jinja that can be handy in this specific use case.


    So, with a list like:

    postbacks = [
      {'campagn_id': 1},
      {'campagn_id': 2},
      {'campagn_id': 2},
      {'campagn_id': 3},
      {'campagn_id': 3},
    ]
    

    And this snippet of Jinja:

    <table>
      {%- for postback in postbacks %}
        {%- if loop.changed(postback.campaign_id) %}
          <tr>
            <td class="expand expand-site">
              {{ postback.campaign_id }}
            </td>
          </tr>
        {%- endif %}
      {%- endfor %}
    </table>
    

    It renders, with some style added for clarity, as:

    table {
      border-collapse: collapse;
    }
    td {
      border: 1px solid;
      padding: 4px;
    }
    <table>
          <tr>
            <td class="expand expand-site">
              1
            </td>
          </tr>
          <tr>
            <td class="expand expand-site">
              2
            </td>
          </tr>
          <tr>
            <td class="expand expand-site">
              3
            </td>
          </tr>
    </table>