Django Template Language: Configuration, Syntax, and Reusability

Django templates are enhanced HTML files processed by a server-side templating engine. The framework includes two built-in engines: Django Template Language (DTL) and Jinja2. The following material focuses on DTL, which is well-suited for monolithic applications, rapid prototyping, and content-driven sites.

Configuring Template Directories

Register template search paths in settings.py before rendering any files. The TEMPLATES setting controls this behavior.

For project-wide templates, create a root-level templates folder and reference it in DIRS:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Setting APP_DIRS to True instructs Django to scan a templates subdirectory inside every installed application.

Global Templates

Create templates/home.html under the project root:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Home</title>
</head>
<body>
  <h1>Welcome to the homepage</h1>
</body>
</html>

Wire a URL to a view in urls.py:

from django.urls import path
from pages.views import home_page

urlpatterns = [
    path('', home_page, name='home'),
]

Then return the template from the view:

from django.shortcuts import render

def home_page(request):
    return render(request, 'home.html')

render() resolves home.html by searching the directories listed in DIRS.

Application-Level Templates

To isolate templates within a specific app, create pages/templates/pages/dashboard.html. Placing files inside an app-specific subdirectory prevents name collisions when multiple apps define templates with identical filenames.

Ensure the application is registered:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages',
]

With APP_DIRS = True, Django automatically discovers templates stored in each registered app’s templates folder.

Template Syntax

DTL inserts dynamic content using double braces for variables and brace-percent pairs for logic constructs.

Variables

Pass data from the view via a context dictionary:

def home_page(request):
    heading = 'Hello from Django'
    return render(request, 'home.html', {'heading': heading})

Insert the value in the template:

<p>{{ heading }}</p>

Conditional Rendering

Use {% if %} blocks to show or hide fragments. Every opening tag must be closed with {% endif %}.

{% if user_tier == 'admin' %}
  <div>Administrator Controls</div>
{% elif user_tier == 'member' %}
  <div>Member Dashboard</div>
{% else %}
  <div>Public Preview</div>
{% endif %}

Iteration

Loop over sequences with {% for %}:

View:

def home_page(request):
    skills = ['Python', 'Django', 'PostgreSQL', 'Docker']
    return render(request, 'home.html', {'skills': skills})

Template:

<ul>
  {% for skill in skills %}
    <li>{{ skill }}</li>
  {% endfor %}
</ul>

Cycling Values

The cycle tag rotates through a set of values on each iteration. Its commonly used to apply alternating row styles:

<style>
  .stripe-a { background: #ffffff; }
  .stripe-b { background: #e5e7eb; }
</style>

<table>
  {% for skill in skills %}
    <tr class="{% cycle 'stripe-a' 'stripe-b' %}">
      <td>{{ skill }}</td>
    </tr>
  {% endfor %}
</table>

Autoescaping

Django automatically escapes HTML characters to protect against cross-site scripting. If a variable contains trusted markup, disable escaping explicitly:

def home_page(request):
    nav_link = '<a href="/about/">About Us</a>'
    return render(request, 'home.html', {'nav_link': nav_link})

Template:

<div>
  {% autoescape off %}
    {{ nav_link }}
  {% endautoescape %}
</div>

When autoescape is on—the default—characters such as < and > are converted to HTML entities.

Filters

Filters modify variables at render time. They follow a pipe symbol.

Change text casing:

{{ headline|upper }}
{{ headline|lower }}

Convert to URL-friendly slug:

{{ page_title|slugify }}

Provide a fallback for empty values:

{{ display_name|default:'Guest' }}

Count characters or items:

{{ headline|length }}

Remove unwanted substrings:

{{ description|cut:'lorem ' }}

Limit length with an ellipsis:

{{ summary|truncatechars:80 }}

Join list elements into a string:

{{ tags|join:', ' }}

Access the first or last item:

{{ tags|first }}
{{ tags|last }}

Round floating-point numbers:

{{ score|floatformat:2 }}

Comments

Hide single lines using {# ... #}:

{# This line is ignored by the parser #}

Hide larger blocks with the comment tag:

{% comment %}
  This entire region
  will not appear in the rendered output.
{% endcomment %}

Loading Static Assets

Reference CSS, JavaScript, and images with the {% static %} tag.

First, define the static URL and additional directories in settings.py:

STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static']

In templates, load the tag library before using it:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
  <link rel="stylesheet" href="{% static 'css/main.css' %}">
</head>
<body>
  <img src="{% static 'images/logo.png' %}" alt="Company Logo">
  <script src="{% static 'js/app.js' %}"></script>
</body>
</html>

Template Inheritance

Define a master layout to eliminate repetition. Create templates/base.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
  <header>Primary Navigation</header>

  {% block content %}
  {% endblock %}

  <footer>Contact Information</footer>
</body>
</html>

Child templates extend the parent and populate named blocks:

{% extends 'base.html' %}

{% block title %}User Dashboard{% endblock %}

{% block content %}
  <h1>Welcome back</h1>
{% endblock %}

Including Partials

Reuse common fragments with {% include %}. Define a partial such as templates/components/notice.html:

<aside class="notice">{{ notice_text }}</aside>

Embed it in any page:

{% include 'components/notice.html' %}

This approach lets you compose pages from modular, reusable pieces.

Tags: Django Django Templates DTL python web development

Posted on Sun, 10 May 2026 22:54:12 +0000 by Langridge