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
templatetags
directory in your app - Create an empty
__init__.py
file 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
if
statements - Looping through blog posts with
for
- Using loop variables like
forloop.first
andforloop.last
- URL generation with the
url
tag - 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
for
tag - 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
forloop
counter. - 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
include
tag 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.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)