The Django Template System is a powerful way to separate presentation logic from business logic in your web application. Templates let you dynamically generate HTML using data passed from views, and they help keep your code modular, reusable, and clean.
What Is the Django Template System?
The Django template system is a text-based template language designed for generating HTML, XML, or other output formats. It includes:
-
Template tags:
{% ... %}
for logic (like loops and conditions) -
Template variables:
{{ ... }}
for inserting dynamic content -
Filters:
{{ variable|filter }}
for formatting content
Step 1: Set Up Templates Directory
A. In Your App
Create the following folder structure inside your app:
myapp/
├── templates/
│ └── myapp/
│ └── index.html
B. Tell Django Where to Look
In settings.py
, update the TEMPLATES
setting (usually already set up):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [], # You can add custom template directories here
'APP_DIRS': True, # Enables loading from app/templates/
...
},
]
✏️ Step 2: Create a Template
myapp/templates/myapp/index.html
<!DOCTYPE html>
<html>
<head>
<title>Django Templates</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
<p>Today is {{ date|date:"F j, Y" }}.</p>
</body>
</html>
Step 3: Use the Template in a View
myapp/views.py
from django.shortcuts import render
from datetime import datetime
def index(request):
context = {
'name': 'Alice',
'date': datetime.now(),
}
return render(request, 'myapp/index.html', context)
Result:
Visiting /
shows:
Hello, Alice!
Today is May 20, 2025.
Template Components
1. Variables ({{ variable }}
)
<p>Welcome, {{ user.username }}!</p>
Django automatically escapes HTML by default to prevent XSS attacks.
2. Tags ({% tag %}
)
Control flow like loops and conditions:
Example:
{% if products %}
<ul>
{% for product in products %}
<li>{{ product.name }} - ${{ product.price }}</li>
{% endfor %}
</ul>
{% else %}
<p>No products available.</p>
{% endif %}
3. Filters ({{ variable|filter }}
)
Filters modify values before display.
Filter | Description |
---|---|
date |
Format date/time values |
length |
Count items in a list |
lower |
Convert string to lowercase |
default |
Provide a default value if empty |
truncatechars:10 |
Truncate text to 10 chars |
Example:
<p>{{ message|truncatechars:20 }}</p>
Template Inheritance
Django encourages DRY design using template inheritance.
A. base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
B. home.html
{% extends 'myapp/base.html' %}
{% block title %}Home{% endblock %}
{% block content %}
<h1>Welcome to the homepage!</h1>
{% endblock %}
Inheritance allows you to define a common layout once and reuse it across pages.
Including Other Templates
You can split your layout into reusable chunks like headers, footers, etc.
includes/navbar.html
<nav>
<a href="/">Home</a> | <a href="/about/">About</a>
</nav>
Use in Template:
{% include 'includes/navbar.html' %}
Template Static Files
A. Add Static Settings
In settings.py
:
STATIC_URL = '/static/'
B. Use Static in Template
{% load static %}
<link rel="stylesheet" href="{% static 'myapp/styles.css' %}">
Put your static files in:
myapp/
└── static/
└── myapp/
└── styles.css
Built-in Security
Django templates automatically:
-
Escape variables (to prevent XSS)
-
Block arbitrary Python execution (safe sandboxed environment)
If you want to render safe HTML (carefully):
{{ html_variable|safe }}
✅ Best Practices
Best Practice | Why It Helps |
---|---|
Use template inheritance | Avoid repetition |
Keep logic out of templates | Use views/models for heavy logic |
Use {% url 'name' %} |
Avoid hardcoding paths |
Use {% static %} for assets |
Ensures correct URL resolution |
Avoid deeply nested templates | Keep it modular and manageable |
⚠️ Common Pitfalls
Mistake | Problem | Fix |
---|---|---|
❌ Forgetting {% load static %} |
Static files won’t load | Add {% load static %} at the top |
❌ No context passed | Variables won’t render | Always pass a context dictionary |
❌ Template not found | Misplaced file or wrong name | Use app/templates/app/template.html |
❌ Using complex logic in template | Templates become hard to maintain | Move logic to views or template tags |
❌ Hardcoding URLs | Breaks when URLs change | Use {% url 'route_name' %} |
Full Example
View (myapp/views.py
)
from django.shortcuts import render
from datetime import datetime
def homepage(request):
return render(request, 'myapp/home.html', {
'user_name': 'Charlie',
'date': datetime.now(),
})
Template (myapp/templates/myapp/home.html
)
{% extends 'myapp/base.html' %}
{% block title %}Home Page{% endblock %}
{% block content %}
<h1>Hi, {{ user_name }}!</h1>
<p>Today is {{ date|date:"l, F j, Y" }}</p>
{% endblock %}
Base Template (myapp/templates/myapp/base.html
)
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
<header>
<h1>My Website</h1>
{% include 'myapp/navbar.html' %}
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
Conclusion
The Django Template System is a robust, secure, and flexible way to generate dynamic content. It enforces clean separation between backend and frontend code, enables reusability through inheritance, and provides great tools like filters, static file handling, and template includes.
Next Steps
You may want to explore:
-
Custom template tags and filters
-
Passing QuerySet objects to templates
-
Working with forms and templates
-
Internationalization in templates