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
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.
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 %}
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
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 %}
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!
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 ))
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
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.
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 %}
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
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 %}
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!
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 ))