🔁 Django For Loop – Loop Through Lists and Querysets in Templates (2025 Guide)
🧲 Introduction – What Is the For Loop in Django Templates?
The {% for %} tag in Django templates lets you iterate over a list, queryset, or any iterable and dynamically generate HTML content. It’s one of the most used tags for displaying collections like blog posts, comments, or navigation menus.
🎯 In this guide, you’ll learn:
- How to loop through data using
{% for %} - How to use
forloopvariables likeforloop.counter - How to handle empty lists with
{% empty %} - Best practices for clean, readable loop output
🔁 Basic Syntax
{% for item in items %}
<p>{{ item }}</p>
{% endfor %}
✅ Loops through each item and renders it.
🧱 Real Example with QuerySet
views.py
def post_list(request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
post_list.html
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
➕ Using {% empty %} for No Results
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% empty %}
<li>No posts found.</li>
{% endfor %}
</ul>
✅ Shows a fallback message when the list is empty.
🧮 Useful forloop Variables
| Variable | Description |
|---|---|
forloop.counter | 1-based index (starts at 1) |
forloop.counter0 | 0-based index |
forloop.revcounter | Reverse index (1-based) |
forloop.revcounter0 | Reverse index (0-based) |
forloop.first | True on first iteration |
forloop.last | True on last iteration |
forloop.parentloop | Access parent loop (for nested) |
🌐 Example with Index and Highlight
<ol>
{% for item in items %}
<li {% if forloop.first %}class="highlight"{% endif %}>
{{ forloop.counter }}. {{ item }}
</li>
{% empty %}
<li>No items available.</li>
{% endfor %}
</ol>
🧩 Nested Loops
{% for category in categories %}
<h2>{{ category.name }}</h2>
<ul>
{% for post in category.posts.all %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% endfor %}
✅ Best Practices
- ✅ Use
{% empty %}for user-friendly empty states - ✅ Limit logic inside loops—prepare data in views
- ✅ Use
forloop.firstandforloop.lastto add special styles - ✅ Paginate large querysets instead of looping all at once
📌 Summary – Recap & Next Steps
🔍 Key Takeaways:
{% for %}loops over iterable data in templates- Supports index tracking, first/last checks, and nested loops
- Use
{% empty %}to handle blank lists gracefully
⚙️ Real-World Relevance:
Use the Django for loop to power blog feeds, product grids, notifications, dropdowns, and much more in dynamic web apps.
❓ Frequently Asked Questions (FAQ)
❓ Can I loop through dictionaries?
🟡 Not directly. Convert it to a list of items:
context = {'mydict': mydict.items()}
❓ What if the list is very large?
✅ Use pagination with Django’s Paginator to load data in chunks.
❓ Can I use continue or break in the loop?
🚫 No. Django templates don’t support Python-style loop control.
❓ How do I access the index inside the loop?
✅ Use forloop.counter (starts at 1) or forloop.counter0 (starts at 0).
❓ How do I loop through model relationships?
✅ Use dot notation:
{% for comment in post.comments.all %}
{{ comment.body }}
{% endfor %}
Share Now :
