GergelyPolonkai
GergelyPolonkai

Reputation: 6421

Insert separator only if didn’t insert one before

I have a template variable product_list, which is a QuerySet of Product objects; Product objects, in turn, have a one-to-many field of Track objects (reverse mapped from Track, of course), which is possible to be empty. I want to create a list of Tracks, grouped by Products like this:

{% for product in product_list %}
    {% if this is not the first product with tracks %}
        <li class="separator"></li>
    {% endif %}

    {% for track in product.tracks %}
        <li>{{track}}</li>
    {% endfor %}
{% endfor %}

The question is, what should I write of if this is not the first product with tracks? I tried ifchanged product but it inserts a separator even on the first iteration (as it changes from "" to "someproduct"). forloop.counter is also not usable here, as it is possible that the first two products won’t have tracks.

One workaround could be to change product_list to track_list like this:

track_list = Track.objects.order_by('product__name')

so I can indeed use ifchanged. It is doable in my case, but I’m still interested in a solution for my first method.

Upvotes: 1

Views: 48

Answers (1)

dani herrera
dani herrera

Reputation: 51705

You should compose the condition. It looks simple, perhaps is not this that your are asking for.

{% for product in product_list %}
    {% if not forloop.first and product.tracks %}
        <li class="separator"></li>
    {% endif %}

    {% for track in product.tracks %}
        <li>{{track}}</li>
    {% endfor %}
{% endfor %}

If this is not a solution for you, I suggest to you to cook data on view and send ready to be parse to template, more easy.

{% for product in product_list %}
    {% if product.should_have_separator %}
        <li class="separator"></li>
    {% endif %}

    {% for track in product.tracks %}
        <li>{{track}}</li>
    {% endfor %}
{% endfor %}

In your view append should_have_separator field dynamically to products should have it:

product_list = Product.objects.....
is_the_first_product = True
for product in product_list:
    is_the_first_product_with_tracks = ( is_the_first_product 
                                        and bool( product.tracks ) )
    product.should_have_separator = not is_the_first_product_with_tracks
    is_the_first_product = False

Upvotes: 1

Related Questions