0

I'm trying to display values from a different list based on the index that is currently being iterated over on another list but cannot figure out how to access the individual items..

{% for row in myarray.all %}
    <tr>
    <th>{{ my_other_array_where_I_cant_access_elements.forloop.counter }}</th>
    <td>{{ row }}</td>
    </tr>
{% endfor %}

As you can see I have tried to use forloop.counter but this doesn't display anything, it just creates an empty table header element.

My other array is defined within the view as the following, and if I remove the forloop.counter then I am able to see the entire array printed to the table header

 my_other_array_where_I_cant_access_elements = ["X", "Y", "Z", "XX", "YY"]

Please let me know if I've missed any required details.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Sayse
  • 42,633
  • 14
  • 77
  • 146
  • Shouldn't it be forloop.counter0 (to have a 0-based index) ? – manuBriot Aug 11 '14 at 14:47
  • @manuBriot - I would expect that to at least show some values if that were the case (for the record I also tried that and it still doesnt show any values) – Sayse Aug 11 '14 at 14:52

2 Answers2

5

It sounds like you want to iterate over two lists at the same time, in other words zip() lists.

If this is the case, it is better to do this in the view and pass inside the context:

headers = ["X", "Y", "Z", "XX", "YY"]
data = zip(headers, myarray.all())
return render(request, 'template.html', {'data': data})

Then, in the template:

{% for header, row in data %}
    <tr>
        <th>{{ header }}</th>
        <td>{{ row }}</td>
    </tr>
{% endfor %}
Alasdair
  • 298,606
  • 55
  • 578
  • 516
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I've just taken a look into implementing this and it isn't possible since `myarray` is actually a more deep rooted array inside another object, and I would like to avoid having to store these headers in a database (where the object is stored).. is there a solution like this on the template side or do I just have to bite the bullet and have the headers in the database? – Sayse Aug 11 '14 at 14:50
  • 1
    @Sayse custom template filter could be an option in this case: http://stackoverflow.com/a/14857664/771848. – alecxe Aug 11 '14 at 14:51
  • Thanks, I'll take a look into implementing that, looks like exactly what I need – Sayse Aug 11 '14 at 15:01
0

There is a possible approach, which I just tried. It only works if you only use the second array as part of a single for loop, though, and does not use the loop index:

arr = ["1-0", "1-1"]     # your first array
arr2 = ["2-0", "2-1"]    # your second array

class wrap(object):
    def __init__(self, ref):
        self.ref = ref
        self.idx = -1
    def next(self):
        self.idx += 1
        return self.ref[self.idx]

return render_to_response('...', { "arr": arr, "wrap": wrap(arr2) })

And the template is:

{% for row in arr %}
<h1>Row {{ row }} at {{ forloop.counter }} matches {{ wrap.matching }} </h1>
{% endfor %}
manuBriot
  • 2,755
  • 13
  • 21