Mat
Mat

Reputation: 86474

How much flexibility is there in a Django for loop?

I am outputting a series of Django objects in a template:

{% for obj in list %}
    ...
{% endfor %}

But I'd like to only output the first five of these, then put the remainder in the seperate <DIV>. The idea being, that I can hide the second half until required.

I envisage something like this, but need to restrict the elements iterated:

{% for obj in list %}
    ...
{% endfor %}

<a href="" onclick="unhide()">Show hidden</a>
<div id="hidden">
    {% for obj in list %}
        ...
    {% endfor %}
</div>

Is it possible to do this within the template alone? It's presentation logic, so I'd rather not pollute the view.

Upvotes: 3

Views: 3215

Answers (3)

Andy Baker
Andy Baker

Reputation: 21567

Struggling with template limitations can often be a sign that life might be simpler if you did more work in your view:

context = {
  'visible_list': mylist[:5],
  'hidden_list': mylist[5:]
}

I'm not saying this is neccesarily any better than the slice filter solution above but it's often worth considering passing your templates a context object with everything set up nicely. It allows you to adapt more easily should the logic get even more complex later on.

Presentation logic sits quite nicely in a view. I don't particularly see it as 'pollution'.

Upvotes: 7

Paolo Bergantino
Paolo Bergantino

Reputation: 488414

You could use slice:

{% for obj in list|slice:":5" %}
    ...
{% endfor %}

<a href="" onclick="unhide()">Show hidden</a>
<div id="hidden">
    {% for obj in list|slice:"5:" %}
        ...
    {% endfor %}
</div>

Upvotes: 18

Alex Martelli
Alex Martelli

Reputation: 881675

Sure, for example you can do the loop twice and within it use forloop.counter in suitable if constructs -- the first time to only do stuff when it's <= 5, the second time only when it's > 5 (remember it's 1-based -- if you want a 0-based one, use forloop.counter0 instead).

Upvotes: 2

Related Questions