Django Template doesn't work with a for loop in range. Why?

VIEWS.PY

def index(request):
    posts = Post.objects.all()
    posts_quantity = range(1)
    return render(request, 'index.html', {'posts':posts, 'posts_quantity':posts_quantity})

HTML

{% for index in posts_quantity %}                        
    <a href = "{% url 'architectural_post' posts.index.slug %}" class = "post">
{% endfor %}

it gives me an error: Reverse for 'architectural_post' with arguments '('',)' not found.

But everything works well if I put 0 instead of index, like this (just for debugging):

{% for index in posts_quantity %}                        
    <a href = "{% url 'architectural_post' posts.0.slug %}" class = "post">
{% endfor %}

Why and how to fix it? Thanks.

The error is occurring because the posts.index.slug is not being passed the correct value. Since you are using the range(1) to loop through the posts_quantity, the index variable is being assigned the value of 0 on each iteration. So, you should use posts.0.slug instead of posts.index.slug in the url tag.

To fix this issue, you can change the code to:

{% for index in posts_quantity %}
<a href = "{% url 'architectural_post' posts.index.slug %}" class = "post">
{% endfor %}

to

{% for index in range %}
<a href = "{% url 'architectural_post' posts.index.slug %}" class = "post">
{% endfor %}

You should change the posts_quantity variable to range(len(posts)) and change the for loop to for index in range(len(posts))

That should fix the issue and correctly pass the slug value to the architectural_post URL.

Django is not interpreting posts.index.slug as posts.0.slug. Instead, Django is trying to find an attribute called index on the posts object.

It's not very intuitive, but that's how it is.


You can fix it by iterating over the posts directly:

{% for post in posts %}
<a href="{% url 'architectural_post' post.slug %}" class="post">
{% endfor %}
Back to Top