Chapter 3: Django if Tag
Django if Tag: The {% if %} tag family ({% if %}, {% elif %}, {% else %}, {% endif %})
Many beginners treat it like “just Python if”, but it’s actually a very limited, very safe mini-language with its own rules, shortcuts, and common pitfalls.
Today we’re going to learn it properly — like I’m sitting next to you, writing in VS Code together, explaining every single pattern you’ll actually use in real projects (not just theory).
We’ll use your existing polls app (Question + Choice + admin + templates) as the playground.
1. The Absolute Basic Form (Everyone Starts Here)
|
0 1 2 3 4 5 6 7 8 |
{% if question.is_active %} <span style="color: green;">This poll is currently active</span> {% endif %} |
→ If question.is_active is True → show the message → If False (or None, empty string, empty list, zero) → show nothing
2. With {% else %} (Most Common Pattern)
|
0 1 2 3 4 5 6 7 8 9 10 |
{% if question.vote_count > 0 %} <p><strong>{{ question.vote_count }}</strong> {{ question.vote_count|pluralize:"vote,votes" }} so far!</p> {% else %} <p style="color: #666; font-style: italic;">Be the first to vote!</p> {% endif %} |
3. Full {% if %} … {% elif %} … {% else %} Chain
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{% if question.pub_date > today %} <span style="color: orange;">Upcoming poll</span> {% elif question.was_published_recently %} <span style="color: green;">Hot & recent!</span> {% elif question.is_active %} <span style="color: blue;">Still active</span> {% else %} <span style="color: gray;">Old / archived</span> {% endif %} |
Very important rule: Django evaluates conditions left to right — first True block wins.
4. Testing for “Falsy” Values (Django’s Special Truthy/Falsy)
Django’s if considers these False (same as Python):
- False
- None
- 0 (integer)
- 0.0 (float)
- empty string “”
- empty list []
- empty dict {}
- empty queryset (.exists() is False)
Everything else is True.
Examples:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{% if question.choices.exists %} Has choices {% else %} No choices yet {% endif %} {% if question.vote_count %} Someone voted! {% else %} Zero votes {% endif %} {% if request.user.is_authenticated %} Welcome back, {{ request.user.username }}! {% else %} <a href="{% url 'login' %}">Please login</a> {% endif %} |
5. Using Operators (Comparisons)
Django supports these inside {% if %}:
- == / !=
- < / <= / > / >=
- in / not in
- is / is not (mostly for None)
Examples:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{% if question.vote_count > 10 %} Popular poll! {% endif %} {% if question.category == "fun" %} <span style="background: #d4edda;">Fun category</span> {% endif %} {% if "politics" in question.category %} Political topic {% endif %} {% if question.pub_date < today %} Past poll {% endif %} {% if question is not None %} Question exists {% endif %} |
Very common real-life pattern:
|
0 1 2 3 4 5 6 7 8 |
{% if question.vote_count >= 5 and question.is_active %} <span style="color: green;">Trending & active</span> {% endif %} |
6. Combining with and, or, not
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{% if question.is_active and question.vote_count > 0 %} Active + has votes {% endif %} {% if not question.is_active %} Hidden from public {% endif %} {% if question.category == "fun" or question.category == "sports" %} Light topic {% endif %} {% if not user.is_authenticated or not perms.polls.add_question %} You cannot add polls {% endif %} |
Tip: Use parentheses for clarity when mixing and/or
|
0 1 2 3 4 5 6 7 8 |
{% if (question.vote_count > 10 and question.is_active) or question.category == "politics" %} Either popular/active OR political {% endif %} |
7. Checking for Existence / Emptiness (Very Frequent)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{% if question.choices.all %} Has choices {% else %} No choices added yet {% endif %} {% if not question.choices.exists %} Empty choices {% endif %} {% if latest_questions %} <!-- show list --> {% else %} <!-- show "no polls" message --> {% endif %} |
8. Testing Permissions (Very Common in Real Projects)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
{% if perms.polls.add_question %} <a href="{% url 'admin:polls_question_add' %}">Add new poll</a> {% endif %} {% if perms.polls.change_question %} <a href="{% url 'admin:polls_question_change' question.pk %}">Edit</a> {% endif %} |
9. Quick Real-World Examples from Your Polls App
Put these in your index.html or detail.html
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<!-- Show vote status --> {% if question.vote_count == 0 %} <p>No votes yet — be the first!</p> {% elif question.vote_count == 1 %} <p>One brave voter!</p> {% else %} <p>{{ question.vote_count }} votes already</p> {% endif %} <!-- Active badge --> <span class="{% if question.is_active %}badge-active{% else %}badge-inactive{% endif %}"> {{ question.is_active|yesno:"Active,Inactive" }} </span> <!-- Conditional link --> {% if user.is_authenticated %} <form method="post" action="{% url 'polls:vote' question.slug %}"> {% csrf_token %} … vote form … </form> {% else %} <p>Please <a href="{% url 'login' %}">login</a> to vote</p> {% endif %} |
Common Beginner Traps & Fixes
| Problem | What happens | Fix / Correct syntax |
|---|---|---|
| {% if question.vote_count > 5 %} works but == fails | Comparison operators are allowed, but spaces matter | Always put spaces around operators: >, ==, != |
| {% if question.vote_count %} shows even when 0 | 0 is falsy | Use {% if question.vote_count != 0 %} or {% if question.vote_count > 0 %} |
| {% if question.category == fun %} fails | No quotes | {% if question.category == “fun” %} |
| {% if not question %} shows wrong thing | question is object | Use {% if not question %} for None / missing |
| Too many nested ifs → messy code | — | Move logic to view/context or custom template tag |
Your Quick Practice Task (Do This Right Now)
Open polls/templates/polls/detail.html or index.html and try adding these:
- {% if question.vote_count > 10 %}Popular!{% endif %}
- {% if question.is_active and question.vote_count > 0 %}Active & voted{% else %}Not ready{% endif %}
- {{ question.category|default:”Uncategorized” }}
- {% if forloop.first %}<strong>Featured poll:</strong>{% endif %} inside a for loop
- {% if not user.is_authenticated %}Please login to vote{% endif %}
Tell me what feels next:
- Which if pattern is still confusing? (comparisons? falsy values? permissions?)
- Want to see 20 more real-life {% if %} examples from different apps?
- Ready to learn {% ifchanged %} / {% ifequal %} (older but still used)?
- Or want to move to custom template tags/filters?
- Or finally ready for Django Forms + Voting + POST + F()?
You’re building very strong template logic now — this {% if %} family is used on almost every page you’ll ever write.
Keep practicing — you’re doing great! 🚀🇮🇳
