[Answered ]-Issues with loops in Django

1đź‘Ť

âś…

Django templates are not programming language. Write all you logic in the view or models, and pass data into the template:

def view(request):
    values = []
    for i in range(10):
         values.append(i) # your custom logic here
    return render_to_response("/path/to/template", {'values': values})

in template:

{% for value in values %}
    <p>{{ value }}</p>
{% endfor %}
👤defuz

1đź‘Ť

The “for i in var” syntax works only where “var” is an iterable eg a list, tuple, set, dict…

I’d suggest the following: Instead of passing the item count to the template, pass in the iterable eg list in. If all you have is a count, you can create an iterable using range(count) in the view. In code

# Extract from view
def view(request):
    # Set up values. Values is a list / tuple / set of whatever you are counting
    values = Product_attributes.objects.all()
    return render_to_response("/path/to/template", {'values': values})

# Extract from template
{% for value in values %}
   <p>{{value}}</p>
{% endfor %}

The “while” tag is not a valid built in tag in django. A list of valid built-in tags can be seen here: https://docs.djangoproject.com/en/dev/ref/templates/builtins/

This way of doing things is not specific to templates only: it has parallels in “regular python” where the canonical way to iterate over a collection is:

for item in iterable:
    # do something with the item
    pass

More information on the “python way” of doing for loops can be found here: http://wiki.python.org/moin/ForLoop

👤Ngure Nyaga

0đź‘Ť

If it’s not appropriate to add the range to your view code (I don’t like adding purely template-ty things to my views), I’d probably create a range filter:

@register.filter
def range(val):
    return range(val)

Then you’d use it like this:

{% for i in count|range %}
<p>{{ i }}</p>
{% endfor %}

There’s also an extremely ugly hack you can use if you don’t want to bother writing any python code for this, it takes advantage of Django’s center (or ljust and rjust) filters which create a string of length of the value provided. You can use it like this:

{% for x in count|center:count %}
<p>{{ forloop.counter }}</p>
{% endfor %}

I wouldn’t recommend doing it this way though, I’m just demonstrating that it’s possible.

👤Andrew Ingram

Leave a comment