Skip to main content

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:

django
{% tag_name [arguments] %}

Some tags require a closing tag:

django
{% 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:

django
{% for item in items %}
{{ item }}
{% endfor %}

Example:

django
<!-- views.py -->
def fruits_view(request):
fruits = ["Apple", "Banana", "Cherry", "Date"]
return render(request, 'fruits.html', {'fruits': fruits})
django
<!-- fruits.html -->
<h1>Fruit List</h1>
<ul>
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
</ul>

Output:

html
<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 iteration
  • forloop.last: Boolean indicating if this is the last iteration

Example with loop variables:

django
{% 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:

django
{% 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:

django
{% 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:

django
<!-- views.py -->
def score_view(request):
score = 85
return render(request, 'score.html', {'score': score})
django
<!-- 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:

html
<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
django
{% 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):

django
<!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>&copy; 2023 My Website</p>
{% endblock %}
</footer>
</body>
</html>

In a child template (page.html):

django
{% 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:

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>&copy; 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:

django
{% include "template_name.html" %}

Example:

Create a reusable navigation component:

django
<!-- 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:

django
<!-- 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:

django
{% 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:

django
{% url 'url_name' [arg1 arg2...] [kwarg1=value1...] %}

Example:

If your urls.py has:

python
# 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:

django
<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:

html
<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:

django
{% 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:

django
<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:

  1. Create a templatetags directory in your app
  2. Create an empty __init__.py file inside it
  3. Create a Python module (e.g., custom_tags.py)
  4. Register your custom tags

Example:

python
# 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:

django
{% 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:

django
{% 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 and forloop.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:

  1. The basic syntax of template tags
  2. Common built-in
  3. Loop variables and additional features in the for tag
  4. How to create custom template tags
  5. 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

Exercises

  1. Create a template that displays a list of products with different CSS classes for odd and even rows using the forloop counter.
  2. Build a navigation menu that highlights the current page using template tags and conditions.
  3. Create a custom template tag that takes a string and returns the reverse of it.
  4. Implement a template that uses the include tag with different context variables to create reusable card components.
  5. 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! :)