Basic Django Template Tags: A Complete Guide

For most Django developers, template tags are where backend data first becomes a real user-facing interface. If you learn the basics well, you can build most Django frontends comfortably using these basic tags.

When building pages in Django, you usually pass data from Python views into HTML templates. But raw HTML alone cannot handle logic like loops, conditions, inheritance, links, or static assets.

That's why Django provides us with templatetags.

Django template tags are special instructions written inside templates that allow you to: - Render dynamic content - Loop through data - Use conditional logic - Reuse layouts - Load static files - Generate URLs - Organize templates cleanly

They are one of the core parts of Django’s templating system.

This article covers the most important basic template tags every Django developer should know.

What Are Template Tags?

Template tags use this syntax:

html

1
{% tag_name %}

They are different from template variables:

html

1
{{ variable }}

The Difference:

Syntax Purpose
{{ ... }} Output a value
{% ... %} Perform template logic

Example:

html

1
2
3
4
5
6
<h1>{{ title }}</h1>

{% if user %}
<p>Hello {{ user.username }}</p>

{% endif %}

If the variable inside {{}} is a Python dict, you can access its elements using:

html

1
{{ variable.key }}

If the variable inside {{}} is a Python list, you can access its elements by index using:

html

1
{{ variable.0 }}

Nested elements:

html

1
{{ variable.key.0 }}

Why Django Uses Template Tags

Django intentionally separates: - Python logic in views/models - Presentation logic in templates

Template tags provide safe, limited logic in HTML without turning templates into full Python scripts.

The Most Important Basic Tags

1.

Conditional rendering.

html

1
2
3
4
{% if user.is_authenticated %}
<p>Welcome back!</p>

{% endif %}

With Else

html

1
2
3
4
5
6
7
8
9
{% if user %}

<p>Hello {{ user.username }}</p>

{% else %}

<p>Please log in.</p>

{% endif %}

Comparisons

html

1
2
3
4
5
{% if age >= 18 %}

<p>Adult</p>

{% endif %}

Logical Operators

html

1
{% if user and is_admin %}

Supports: - and - or - not

2.

Loop through lists, querysets, tuples, etc.

html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<ul>

{% for post in posts %}

    <li>{{ post.title }}</li>

{% endfor %}

</ul>

Empty Fallback:
```html
{% for post in posts %}

    <li>{{ post.title }}</li>

{% empty %}

    <li>No posts found.</li>

{% endfor %}

Loop Variables

Inside loops you can use: - {{ forloop.counter }} -> counter starting at 1 - {{forloop.counter0}} -> counter starting at 0 - {{ forloop.first }} -> first element in the loop - {{ forloop.last }} -> last element in the loop

Example:

html

1
2
3
4
5
{% for item in items %}

<p>{{ forloop.counter }}. {{ item }}</p>

{% endfor %}

3. {% block %} and {% extends %}

Used for template inheritance.

Base Template:

html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- base.html -->
<html>
    <body>

        {% block content %}
        {% endblock %}

    </body>
</html>

Child Template:
```html
{% extends "base.html" %}

{% block content %}

<h1>Home Page</h1>

{% endblock %}

This let's you reuse the full HTML baseline and content that you want rendered multiple times over.

Typical components inside base.html: - Header - Footer - Navigation - Layout structure

4.

Insert another template.

html

1
{% include "partials/navbar.html" %}

Great for isolated, yet reusable components: - Navbar - Footer - Cards - Alerts - CTA - Sign ups

5.

Generate URLs dynamically using Django URL names.

Instead of hardcoding:

html

1
<a href="/posts/">

Use:

html

1
<a href="{% url 'posts' %}">

With Arguments

html

1
<a href="{% url 'post_detail' post.id %}">

Why Important

Never hardcode URLs in your templates. When using url-tags they automatically resolve correctly if URLs change and the templates still work without needing to change them.

6.

Used for CSS, JS, images, etc. -> generally all static content

html

1
{% load static %}

Then:

html

1
<link rel="stylesheet" href="{% static 'css/style.css' %}">

Example Image

html

1
2
3
4
{% extends 'base.html' %}
{% load static %}

<img src="{% static 'img/logo.png' %}">

7.

Critical for forms using POST.

html

1
2
3
4
<form method="post">
    {% csrf_token %}
    ...
</form>

Protects against Cross-Site Request Forgery.

Django requires this tag in POST forms. Otherwise Django will raise an exception.

Want to know more about {% csrf_token %} and how it's implemented properly? csrf_token explained Want to understand the attack this protects against? What is CSRF?

8.

Template comments not visible in HTML source.

html

1
2
3
4
5
{% comment %}

    Temporary block

{% endcomment %}

9.

Store a temporary variable.

html

1
2
3
4
5
{% with total=cart.items.count %}

    <p>{{ total }} items</p>

{% endwith %}

Useful when repeating expensive expressions or when loading tags with a return value.

10.

Current date/time.

bash

1
{% now "Y" %}

Example:

html

1
<p>© {% now "Y" %}</p>

Example Page:

html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{% extends 'base.html' %}
{% load static %}

{% block content %}

<h1>Blog Posts</h1>

<ul>
{% for post in posts %}
    <li>
        <a href="{% url 'post_detail' post.id %}">
            {{ post.title }}
        </a>
    </li>
{% empty %}
    <li>No posts yet.</li>
{% endfor %}
</ul>

{% endblock %}

Common Mistakes:

Forgetting {% endfor %} or {% endif %}

html

1
{% for item in items %}

Will raise an exception!

Must close:

{% endfor %} or {% endif %}

Using {{ }} Instead of {% %}

Wrong:

html

1
{{ if user }}

Correct:

html

1
2
3
4
5
{% if user %}
.
.
.
{% endfor %}

Hardcoding URLs

Bad: href="/posts/5/"

Correct:

html

1
{% url 'post_detail' post.id %}

Forgetting csrf_token

Django will raise an exception

Putting Too Much Logic in Templates

Avoid complex logic in templates.

Do heavy work in: - Views - Models - Services

Templates should stay readable.

Template Tags give Django templates controlled power: - Dynamic pages - Clean layouts - Reusability - Safe rendering - Maintainability

Without tags, templates would be static HTML.

Template Tags are small instructions embedded in HTML that let Django assemble pages dynamically.

Most Important Tags to Memorize: - {% if %}{% endif %} - {% for %}{% endfor %} - {% extends %} - {% block %} - {% include %} - {% url %} - {% load static %} - {% csrf_token %}

Basic Django template tags are intentionally limited - but that limitation is a strength. They keep presentation logic clean while still giving enough power to build dynamic pages efficiently.

If you learn the basics well, you can build most Django frontends comfortably using these basic tags.

For most Django developers, template tags are where backend data first becomes a real user-facing interface.

If basic templatetags are not enough for your project, use your own: Write Your Own Custom Templatetags

Join the Newsletter

Practical insights on Django, backend systems, deployment, architecture, and real-world development — delivered without noise.

Get updates when new guides, learning paths, cheat sheets, and field notes are published.

No spam. Unsubscribe anytime.



There is no third-party involved so don't worry - we won't share your details with anyone.