Chapter 4: Django for Tag

for Tag: {% for %} — the loop tag.

This tag appears in almost every real template you will ever write.

Many beginners write it once or twice, see it “kind of works”, and never really understand its full power, its special variables, its traps, and how to make it beautiful and maintainable.

Today I’m going to teach you {% for %} the way a good senior would teach it: slowly, with real examples from your polls app, showing every useful pattern, every special variable, every common mistake, and how professionals actually write loops in 2026.

We will build everything together — step by step — so that after this lesson you can confidently write any kind of loop you will ever need.

1. The Absolute Simplest Form (What Everyone Starts With)

HTML

That’s it.

  • latest_questions must be a list, queryset, or any iterable passed from the view
  • Inside the loop you get access to the current item (question)
  • After the loop ends → no more items → loop finishes

2. The {% empty %} Clause — Very Important in Real Projects

HTML

Why {% empty %} is golden:

  • Handles the “no items” case gracefully
  • Prevents ugly empty <ul></ul> or broken layout
  • Used in 90%+ of real list templates

3. All Built-in Loop Variables (Memorize These)

Inside any {% for %} loop Django gives you these special variables automatically:

Variable What it gives Example output (when 5 items)
forloop.counter 1-based index 1, 2, 3, 4, 5
forloop.counter0 0-based index 0, 1, 2, 3, 4
forloop.revcounter Countdown from end (1-based) 5, 4, 3, 2, 1
forloop.revcounter0 Countdown from end (0-based) 4, 3, 2, 1, 0
forloop.first True only on first iteration True, False, False…
forloop.last True only on last iteration False, False, …, True
forloop.parentloop Access parent loop in nested loops See nested example below

4. Real-World Examples Using Loop Variables

Example A: Numbered list with “Featured” on first item

HTML

Example B: Zebra striping (alternating row colors)

HTML

Or simpler with forloop.counter0:

HTML

Example C: Show separator only between items (not after last)

HTML

Example D: Nested loops (very common with related objects)

HTML

→ forloop.parentloop.counter gives you the outer question number

5. Common Beginner Mistakes & How to Fix Them

Mistake What happens Correct way
{% for question in questions %} → nothing shows Forgot to pass latest_questions from view Check view: context = {“latest_questions”: qs}
Empty list shows ugly blank space No {% empty %} Always add {% empty %} block
{{ forloop.counter }} shows nothing Typo: forloop (no space) It’s forloop — one word
Want reverse order but don’t know how Sort in view: .order_by(‘-pub_date’)
Nested loop shows wrong number Using forloop.counter instead of parentloop Use forloop.parentloop.counter

6. Pro Tips Used in Real 2026 Projects

  • Always add {% empty %} — even if just <p>No items</p>
  • Use forloop.first for special first-item styling
  • Use forloop.last to avoid trailing commas/separators
  • Prefer view logic for complex sorting/filtering — keep template loops simple
  • If loop is very long → add {% if forloop.counter0 < 20 %} … pagination in view is better

Your Quick Practice Task (Do This Right Now)

Open polls/templates/polls/index.html and improve your question loop:

  1. Add {{ forloop.counter }}. before each question
  2. Add {% if forloop.first %}<strong>Newest:</strong>{% endif %}
  3. Add {% empty %} message with link to admin
  4. Add separator only between items (use {% if not forloop.last %}<hr>{% endif %})
  5. Try nested choice loop inside one question (show choices with forloop.parentloop.counter)

Tell me what you want next:

  • Which part of {% for %} is still confusing? (loop variables? empty? nested?)
  • Want 10 more real-life {% for %} examples from different apps?
  • Ready to learn {% regroup %} (grouping items in loop)?
  • Or ready to move to Django Forms + Voting + POST handling?

You’re getting very strong with template logic — this {% for %} tag is used on almost every page you’ll ever build.

Keep practicing — you’re doing excellent! 🚀🇮🇳

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *