Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Mastering Django Templates: Configuration, Syntax, and Reusability

Tech 1

Django templates serve as dynamic HTML documents, enabling the insertion of contextual data directly into the frontend. Rather than constructing HTML strings within view functions, templates allow developers to separate presentation logic from business logic. This approach significantly enhances code reusability, as common page structures—such as headers, navigation bars, and footers—can be defined once and shared across multiple pages. While Django supports third-party engines like Jinja2, the default backend, Django Template Language (DTL), is the most commonly utilized.

Template Configuration

Before rendering templates, their locations must be registered in the project's settings.py file. Within the TEMPLATES array, the DIRS key accepts a list of filesystem paths where the template loader should search for tmeplate files. Typically, a directory named templates is created at the project root.

# settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates'],
        'APP_DIRS': True,
        # ... other configurations
    },
]

Setting APP_DIRS to True permits Django to discover templates inside individual application directories, provided those applications are listed in INSTALLED_APPS.

Global vs. Application Templates

When a template is requested, Django searches configured directories in a specific order. A global template resides in the project-level templates folder, whereas an app-level template is stored within an application's templates subdirectory (e.g., blog/templates/blog/homepage.html). Using app-level templates requires ensuring the application name (e.g., 'blog') is added to INSTALLED_APPS.

To render a template, import the render shortcut in your views module.

# blog/views.py

from django.shortcuts import render

def home_view(request):
    return render(request, 'blog/homepage.html')

Template Syntax and Tags

DTL utilizes special tags to inject logic and variables into HTML structures. Variables are enclosed in double curly braces {{ }}, while control logic uses percent-brace tags {% %}.

Variables

Data calculated in the view is passed to the template via a dictionary context.

# blog/views.py

def home_view(request):
    greeting = 'Welcome to the platform'
    return render(request, 'blog/homepage.html', {'greeting': greeting})

The template accesses this data directly:

<div>{{ greeting }}</div>

Conditionals

Use {% if %}, {% elif %}, {% else %}, and {% endif %} to control rendering based on boolean expressions.

# blog/views.py

def home_view(request):
    access_level = 2
    return render(request, 'blog/homepage.html', {'access_level': access_level})
{% if access_level == 0 %}
  <span>Private</span>
{% elif access_level == 1 %}
  <span>Premium Only</span>
{% elif access_level == 2 %}
  <span>Members Only</span>
{% else %}
  <span>Public</span>
{% endif %}

Iteration

Lists and querysets can be iterated over using the {% for %} and {% endfor %} tags.

# blog/views.py

def home_view(request):
    categories = ['Technology', 'Science', 'Design', 'Engineering']
    return render(request, 'blog/homepage.html', {'categories': categories})
<ul>
  {% for category in categories %}
  <li>{{ category }}</li>
  {% endfor %}
</ul>

Alternating Values with cycle

The cycle tag rotates through a series of strings or variables on each iteration, which is highly effective for applying alternating CSS classes (like zebra-striping) to table rows or lists.

<style>
  .row-odd { background-color: #f2f2f2; }
  .row-even { background-color: #ffffff; }
</style>

<ul>
  {% for category in categories %}
  <li class="{% cycle 'row-odd' 'row-even' %}">{{ category }}</li>
  {% endfor %}
</ul>

Automatic HTML Escaping

By default, Django escapes hazardous characters to mitigate Cross-Site Scripting (XSS) vulnerabilities. If a variable contains trusted HTML that must be rendered as actual DOM elements, the {% autoescape off %} block can be used.

# blog/views.py

def home_view(request):
    promo_html = '<a href="/offers">Current Offers</a>'
    return render(request, 'blog/homepage.html', {'promo_html': promo_html})
{% autoescape off %}
  <div>{{ promo_html }}</div>
{% endautoescape %}

Filters

Filters transform variable output using the pipe | character within variable tags.

<!-- Casing -->
{{ username | lower }}
{{ username | upper }}

<!-- URL-friendly slugs -->
{{ article_title | slugify }}

<!-- Fallback values -->
{{ user_status | default:"Inactive" }}

<!-- Character count -->
{{ description | length }}

<!-- Removing substrings -->
{{ document_text | cut:"draft_" }}

<!-- Truncating with ellipsis -->
{{ long_summary | truncatechars:50 }}

<!-- Joining lists -->
{{ tags | join:" | " }}

<!-- Accessing list endpoints -->
{{ items | first }}
{{ items | last }}

<!-- Floating-point precision -->
{{ price | floatformat:2 }}

Comments

Single-line comments are written with {# #}, while multi-line blocks use the {% comment %} tag.

{# This is a hidden note #}

{% comment %}
  <p>This entire block will not be rendered.</p>
  <p>Useful for debugging or temporarily disabling HTML.</p>
{% endcomment %}

Loading Static Assets

Static files (CSS, JavaScript, images) require configuration in settings.py before they can be linked in templates.

# settings.py
import os

STATIC_URL = 'static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

Inside the template, load the static template tag library first, then reference the files using the {% static %} tag.

{% load static %}
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="{% static 'css/stylesheet.css' %}">
</head>
<body>
  <img src="{% static 'img/logo.png' %}" alt="Site Logo">
</body>
</html>

Template Inheritance

Inheritance allows a base skeleton template to define a common layout with placeholder blocks, which child templates can then populate. This promotes maximum DRY (Don't Repeat Yourself) principles.

Base layout file (base_layout.html):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Application</title>
</head>
<body>
  <nav>Global Navigation</nav>
  {% block main_content %}{% endblock %}
  <footer>Global Footer</footer>
</body>
</html>

Child template (homepage.html) extending the base:

{% extends 'base_layout.html' %}

{% block main_content %}
  <h1>Welcome to the Homepage</h1>
  <p>Specific page content goes here.</p>
{% endblock %}

Template Inclusion

The {% include %} tag injects a reusable sub-template (component) into the current document. This is ideal for UI fragments that appear in multiple places but do not require a full inheritance hierarchy.

Component file (card_widget.html):

<div class="card">
  <h3>Reusable Card Component</h3>
</div>

Including the component in another template:

<body>
  {% include 'card_widget.html' %}
  {% include 'card_widget.html' %}
</body>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.