Django Template Tags
Introduction
Django template tags are special elements in Django's templating language that allow you to add logic, control flow, and dynamic behavior to your templates. Unlike simple variable interpolation which just displays data, template tags enable you to perform operations like loops, conditionals, URL generation, and much more within your HTML templates.
Think of template tags as mini functions that process data or control how your template is rendered. They are essential for creating dynamic web pages in Django applications without writing JavaScript or embedding Python code directly in your HTML.
Basic Syntax
Django template tags use a specific syntax that distinguishes them from regular HTML and text. The basic format is:
{% tag_name [arguments] %}
Some tags require a closing tag:
{% tag_name [arguments] %}
content affected by the tag
{% endtag_name %}
Let's explore the most common and useful template tags in Django.
Common Template Tags
The for Tag
The for tag allows you to loop through each item in a sequence (like a list, tuple, or queryset).
Syntax:
{% for item in items %}
{{ item }}
{% endfor %}
Example:
<!-- views.py -->
def fruits_view(request):
fruits = ["Apple", "Banana", "Cherry", "Date"]
return render(request, 'fruits.html', {'fruits': fruits})
<!-- fruits.html -->
<h1>Fruit List</h1>
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>
Output:
<h1>Fruit List</h1>
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
<li>Date</li>
</ul>
The for tag also provides useful variables within the loop:
forloop.counter: The current iteration (1-indexed)forloop.counter0: The current iteration (0-indexed)forloop.first: Boolean indicating if this is the first iterationforloop.last: Boolean indicating if this is the last iteration
Example with loop variables:
{% for fruit in fruits %}
<div class="{% if forloop.first %}first-item{% endif %}">
{{ forloop.counter }}. {{ fruit }}
{% if forloop.last %}<span>(last item)</span>{% endif %}
</div>
{% endfor %}
You can also use an empty clause to display content when the list is empty:
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% empty %}
<li>No fruits available</li>
{% endfor %}
The if, elif, and else Tags
The if tag evaluates a variable or expression and conditionally renders content based on the result.
Syntax:
{% if condition %}
content to render when condition is true
{% elif another_condition %}
content to render when another_condition is true
{% else %}
content to render when all conditions are false
{% endif %}
Example:
<!-- views.py -->
def score_view(request):
score = 85
return render(request, 'score.html', {'score': score})
<!-- score.html -->
<h1>Your Score: {{ score }}</h1>
{% if score >= 90 %}
<p>Grade: A - Excellent!</p>
{% elif score >= 80 %}
<p>Grade: B - Good job!</p>
{% elif score >= 70 %}
<p>Grade: C - Fair.</p>
{% else %}
<p>Grade: D or below - Needs improvement.</p>
{% endif %}
Output:
<h1>Your Score: 85</h1>
<p>Grade: B - Good job!</p>
You can use various operators in conditions:
- Comparison:
==,!=,<,>,<=,>= - Logical:
and,or,not - Membership:
in,not in
{% if user.is_authenticated and user.is_staff %}
<p>You have admin privileges</p>
{% endif %}
{% if "apple" in favorite_fruits %}
<p>You like apples!</p>
{% endif %}
The block and extends Tags
The block and extends tags are fundamental to Django's template inheritance system, allowing you to create base templates and extend them.
In a base template (base.html):
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Default Title{% endblock %}</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
{% block header %}
<h1>My Website</h1>
{% endblock %}
</header>
<main>
{% block content %}
<p>Default content</p>
{% endblock %}
</main>
<footer>
{% block footer %}
<p>© 2023 My Website</p>
{% endblock %}
</footer>
</body>
</html>
In a child template (page.html):
{% extends "base.html" %}
{% block title %}About Us{% endblock %}
{% block content %}
<h2>About Our Company</h2>
<p>We are an amazing company founded in 2010.</p>
{% endblock %}
Rendered output of page.html:
<!DOCTYPE html>
<html>
<head>
<title>About Us</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>My Website</h1>
</header>
<main>
<h2>About Our Company</h2>
<p>We are an amazing company founded in 2010.</p>
</main>
<footer>
<p>© 2023 My Website</p>
</footer>
</body>
</html>
The include Tag
The include tag lets you include the contents of another template into the current template.
Syntax:
{% include "template_name.html" %}
Example:
Create a reusable navigation component:
<!-- nav.html -->
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
Include it in another template:
<!-- page.html -->
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<header>
{% include "nav.html" %}
</header>
<main>
<h1>Welcome to my website</h1>
</main>
</body>
</html>
You can also pass variables to the included template:
{% include "user_greeting.html" with username=user.username is_admin=user.is_staff %}
The url Tag
The url tag generates a URL based on Django's URL patterns, which helps avoid hardcoding URLs in templates.
Syntax:
{% url 'url_name' [arg1 arg2...] [kwarg1=value1...] %}
Example:
If your urls.py has:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('product/<int:id>/', views.product_detail, name='product_detail'),
path('category/<str:category>/', views.category, name='category_view'),
]
In your template, you can use:
<a href="{% url 'home' %}">Home</a>
<a href="{% url 'product_detail' id=42 %}">View Product #42</a>
<a href="{% url 'category_view' category='electronics' %}">Electronics</a>
Which would render as:
<a href="/">Home</a>
<a href="/product/42/">View Product #42</a>
<a href="/category/electronics/">Electronics</a>
The static Tag
The static tag helps generate URLs for static files (CSS, JavaScript, images) in your templates.
First, ensure you have {% load static %} at the top of your template.
Example:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
<script src="{% static 'js/main.js' %}"></script>
</head>
<body>
<img src="{% static 'images/logo.png' %}" alt="Logo">
<h1>Welcome to my site</h1>
</body>
</html>
The csrf_token Tag
The csrf_token tag inserts a CSRF (Cross-Site Request Forgery) token into forms for security. This is essential for all POST forms in Django.
Example:
<form method="post" action="/contact/">
{% csrf_token %}
<label for="name">Name:</label>
<input type="text" id="name" name="name">
<button type="submit">Submit</button>
</form>
Creating Custom Template Tags
Sometimes, built-in template tags aren't enough for your specific needs. Django allows you to create custom template tags.
Steps to create a custom template tag:
- Create a
templatetagsdirectory in your app - Create an empty
__init__.pyfile inside it - Create a Python module (e.g.,
custom_tags.py) - Register your custom tags
Example:
# myapp/templatetags/custom_tags.py
from django import template
from datetime import datetime
register = template.Library()
@register.simple_tag
def current_time(format_string):
return datetime.now().strftime(format_string)
@register.filter
def multiply(value, arg):
return value * arg
Usage in template:
{% load custom_tags %}
<p>Current time: {% current_time "%Y-%m-%d %H:%M" %}</p>
<p>Price with quantity: ${{ product.price|multiply:quantity }}</p>
Real-world Application: Building a Blog Template
Let's combine multiple template tags to build a simple blog post listing page:
{% extends "base.html" %}
{% load static %}
{% block title %}My Blog Posts{% endblock %}
{% block content %}
<div class="blog-container">
<h1>Latest Blog Posts</h1>
{% if blog_posts %}
{% for post in blog_posts %}
<article class="blog-post {% if forloop.first %}featured{% endif %}">
<h2>
<a href="{% url 'blog_detail' id=post.id %}">{{ post.title }}</a>
{% if post.is_new %}<span class="badge">New!</span>{% endif %}
</h2>
{% if post.image %}
<img src="{% static post.image %}" alt="{{ post.title }}">
{% endif %}
<p class="post-meta">
Posted on {{ post.date_published|date:"F j, Y" }}
by {{ post.author.name }}
</p>
<div class="excerpt">
{{ post.excerpt|truncatewords:50 }}
</div>
<a href="{% url 'blog_detail' id=post.id %}" class="read-more">
Read More
</a>
</article>
{% if not forloop.last %}
<hr class="divider">
{% endif %}
{% endfor %}
{% include "blog/pagination.html" with page=blog_posts %}
{% else %}
<p class="no-posts">No blog posts found. Please check back later!</p>
{% endif %}
</div>
{% endblock %}
This example demonstrates:
- Template inheritance with
extends - Loading static files
- Conditional rendering with
ifstatements - Looping through blog posts with
for - Using loop variables like
forloop.firstandforloop.last - URL generation with the
urltag - Including another template with
include - Displaying formatted dates
Summary
Django template tags are powerful tools that bring logic and dynamic behavior to your templates while maintaining clean separation between presentation and business logic. In this guide, we've covered:
- The basic syntax of template tags
- Common built-in
- Loop variables and additional features in the
fortag - How to create custom template tags
- A real-world example combining multiple tags in a blog template
By mastering Django template tags, you can create more dynamic, maintainable, and DRY (Don't Repeat Yourself) templates that enhance your Django applications.
Additional Resources
- Django Official Documentation on Template Tags
- Django Template Language Overview
- Creating Custom Template Tags and Filters
Exercises
- Create a template that displays a list of products with different CSS classes for odd and even rows using the
forloopcounter. - Build a navigation menu that highlights the current page using template tags and conditions.
- Create a custom template tag that takes a string and returns the reverse of it.
- Implement a template that uses the
includetag with different context variables to create reusable card components. - Build a complete blog homepage template with sidebar sections for categories, recent posts, and a search form.
💡 Found a typo or mistake? Click "Edit this page" to suggest a correction. Your feedback is greatly appreciated!