Django counter in loop to index list

Question:

I’m passing two lists to a template. Normally if I was iterating over a list I would do something like this

{% for i in list %}

but I have two lists that I need to access in parallel, ie. the nth item in one list corresponds to the nth item in the other list. My thought was to loop over one list and access an item in the other list using forloop.counter0 but I can’t figure out the syntax to get that to work.

Thanks

Asked By: JPC

||

Answers:

don’t think you’ll be able to do it like that. You’ll need either a template tag, or much better, to align the lists in your view logic, before passing an aligned data structure to you template.

Answered By: simon

You can’t. The simple way is to preprocess you data in a zipped list, like this

In your view

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)

Then in you template :

{% for x, y in zipped %}
    {{ x }} - {{ y }}
{% endfor %}
Answered By: Xavier Barbosa

Sounds like you’re looking for my django-multiforloop. From the README:

Rendering this template

{% load multifor %}
{% for x in x_list; y in y_list %}
  {{ x }}:{{ y }}
{% endfor %}

with this context

context = {
    "x_list": ('one', 1, 'carrot'),
    "y_list": ('two', 2, 'orange')
}

will output

one:two
1:2
carrot:orange
Answered By: Gabriel Grant

I ended up having to do this:

{% for x in x_list %}
  {% for y in y_list %}
    {% if forloop.counter == forloop.parentloop.counter %}
       Do Something
    {% endif %}
  {% endfor %}
{% endfor %}
Answered By: fmdra

To access an iterable using a forloop counter I’ve coded the following very simple filter:

from django import template

register = template.Library()

@register.filter
def index(sequence, position):
    return sequence[position]

And then I can use it at my templates as (don’t forget to load it):

{% for item in iterable1 %}
  {{ iterable2|index:forloop.counter0 }}
{% endfor %}

Hope this helps someone else!

Answered By: Caumons

I solved this problem by adding placeholder properties such as template_property1 to one of the models.

Then add logic in the views.py function to loop through both models and assign values across:

model1 = Model1.objects.all()
model2 = Model2.objects.all()

for m1 in model1:                          (loop through model1) 
  for m2 in model2:                        (loop through model2)
    if m2.FK == m1:                        (MATCH SOME CRITERIA)   
      m1.template_property1 = m2.property  (ASSIGN VALUE)

then access all values through a single Model object int the template
for m1 in model1
{{ model1.template_property1 ))

Answered By: Ludo
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.