How to create and use Django templates
Templates play a crucial role in defining the look and feel of your web pages while maintaining a clean separation of concerns between the logic, which is handled by views, and the user interface.
In this article, you’ll learn more about Django templates, how to set them up, as well as the many ways to use them.
What are Django templates?
The template system in Django is designed to separate the presentation of data from the underlying logic. Templates are essentially HTML files that contain dynamic content, allowing you to display data passed from your views.
The Django Template Language (DTL) provides placeholders and logic, like loops and conditionals, to insert dynamic data into HTML.
In addition to simplifying the development process, it makes your project structure more organized when deploying it to a Django virtual private server (VPS).
Setting up Django templates
Setting up templates in Django is not difficult at all. Here’s a quick guide.
How to create a template
To create a template in Django, you need to create an HTML file inside a templates directory. The directory structure might look like this:
myproject/ │ ├── myapp/ │ ├── templates/ │ │ └── myapp/ │ │ └── homepage.html │ └── views.py │ └── manage.py
In this structure, Django automatically looks for templates in the templates directory of your app. You can further organize templates inside app-specific folders (like myapp/homepage.html), ensuring that each app has its own templates.
Here’s an example of a simple template (homepage.html):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home</title> </head> <body> <h1>Welcome to {{ site_name }}</h1> <p>{{ message }}</p> </body> </html>
In this template, {{ site_name }} and {{ message }} are placeholders that will be filled with dynamic data passed from the view.
Rendering Templates in views
To render a template, you need to pass it to the view using Django’s render() function. Here’s an example of how to render the homepage.html template with some context data in a function-based view (FBV):
from django.shortcuts import render def homepage(request): context = { 'site_name': 'My Django Website', 'message': 'This is the homepage content!' } return render(request, 'myapp/homepage.html', context)
In this example, render() combines the template (homepage.html) with data inside context. Context is a dictionary containing the data that Django will insert into the template (site_name and message).
When a user visits this page, the placeholders {{ site_name }} and {{ message }} in the template will be replaced by “My Django Website” and “This is the homepage content!” respectively, as specified in context.
Using template tags and filters
Django templates also support template tags and filters, which allow you to add dynamic content and logic inside your HTML files.
Template tags enable you to perform logic inside templates, such as loops and conditionals, instead of directly rendering the value. For example, the following code include an if condition:
{% if user.is_authenticated %} <p>Welcome back, {{ user.username }}!</p> {% else %} <p>Hello, Guest!</p> {% endif %}
Meanwhile, template filters take values from variables and modify it for display purposes. For instance the following filter take article publishing date and show it in a MMMM/DD/YYY format:
<p>Published on {{ article.published_date|date:"F j, Y" }}</p>
Inheriting templates
Django supports template inheritance, allowing you to create base templates that other templates can extend. This is especially useful for maintaining a consistent layout across multiple pages, such as a common header and footer.
Creating a base template
The structure of the base template (base.html) is the same as other templates. Here’s an example code:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{% block title %}My Site{% endblock %}</title> </head> <body> <header> <h1>Site Header</h1> </header> <main> {% block content %} <!-- Page-specific content goes here --> {% endblock %} </main> <footer> <p>Footer Content</p> </footer> </body> </html>
Extending a template
To extend the base template, create a new template with the {% template %} tag. Here’s a code example of a child template (homepage.html):
{% extends 'base.html' %} {% block title %}Home Page{% endblock %} {% block content %} <h2>Welcome to the homepage!</h2> <p>This is the homepage content.</p> {% endblock %}
By extending the base template, you can reuse the header and footer across different pages, maintaining a consistent layout and avoiding repetition.
Including static files in templates
Templates also allow you to reference static files (like CSS, JavaScript, or images) using the {% static %} template tag. For example, to include a CSS file:
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
Make sure you’ve set up your static file directories correctly in settings.py:
STATIC_URL = '/static/'
By effectively using Django’s template system, you can create dynamic, data-driven web pages and maintain a clean separation between logic and presentation.
Context variables in templates
Context variables let you pass data from your views to templates for rendering. They enable you to process dynamic data that changes based on the process in your view. For example, you can make a web page that automatically updates to show the latest post.
To use context variables, add a key-value pair in your views’ dictionary. The key specifies the variable names, while the value is the data you want to pass.
In this simple example, we create the latest_posts and page_title context variables in the homepage’s view. The latest_posts fetches data from the latest_posts queryset while page_title passes the page title:
from django.shortcuts import render from .models import Post def home(request): # Query the latest blog posts latest_posts = Post.objects.order_by('-published_date')[:5] # Get the 5 most recent posts context = { 'latest_posts': latest_posts, 'page_title': 'Home - My Blog', } return render(request, 'home.html', context)
To render the context variable in your template, call them by writing their names inside the placeholder tags. For example, if you have a variable called data, display it using {{ data }}.
Let’s insert the simple code example above into the home.html template. The code should look as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ page_title }}</title> </head> <body> <h1>Latest Blog Posts</h1> <ul> {% for post in latest_posts %} <li> <h2>{{ post.title }}</h2> <p>{{ post.content|truncatewords:30 }}</p> <!-- Show a snippet of the content --> <a href="{% url 'post_detail' post.id %}">Read more</a> </li> {% empty %} <li>No posts available.</li> {% endfor %} </ul> </body> </html>
Based on our previous explanation, the example code renders the page_title variable since we insert it using placeholders. However, we use template tags to call the latest_post context variable and apply logic to process the data.
In the example above, we use for loop to iterate through the fetched posts, pulling data like truncated content, ID, and title.
Working with template blocks
Your website might have multiple pages with the same layout but different content. For example, the home’s head tags contain the blog name, but it changes to About me on the contact page.
Instead of creating different templates for each page, Django provides blocks that serve as a dynamic content placeholder. You can create one using a template tag like so:
{% block name %}HTML content{% endblock %}
To use blocks, you need at least two templates – one for the base and another for the inherited content.
Let’s consider the previous example of the home and contact page. To begin, create a base.html template that gives the basic structure for your content. The content looks as follows:
<!-- base.html --> <!DOCTYPE html> <html> <head> <title>{% block title %}Default Title{% endblock %}</title> </head> </html>
Then, create two child templates that will extend the base.html file’s content. The basic structure looks like this:
<!-- child.html --> {% extends "base.html" %} {% block title %}Child Page Title{% endblock %}
Replace Child Page Title according to the home and contact information page’s title. Now, define the view to render these templates:
# views.py from django.shortcuts import render def home(request): return render(request, 'home.html') def about(request): return render(request, 'contactinfo.html')
Specify the URL path that will render child template views in the urls.py file:
# urls.py from django.urls import path # import your views from .views import home, contactinfo urlpatterns = [ path('', home, name='home'), path('contactinfo/', contactinfo, name='contactinfo'), ]
Since we set the home path as empty, you can render the template by simply entering your website domain name. Meanwhile, the contact information content shows in domain.com/contactinfo/.
Conclusion
Django templates are HTML content of your website that loads dynamic data from views. They separate the content from the logic, enabling you to modify or reuse the code more easily.
Template files are located inside your Django application’s templates folder. To insert data passed from views, use the {{ variable }} tag. For example, if you want to display a title from the view, add {{ title }}.
To apply logic to the rendered data, use the {% variable %} tag. For example, you can iterate through a context variable and fetch additional data. You can also use the if statement to process the content.
Templates can inherit content from their child using blocks. To do so, insert {% block name %}HTML content{% endblock %} into both the base and child templates to specify the the dynamic content placeholder.
How to use Django templates FAQ
What is the Django template language?
Django’s template language is a text-based system for defining dynamic HTML. It uses {{ variables }} to render data, {% tags %} for logic (if/for loops), and filters like {{ value|length }} to transform data. It lets you separate Python logic from presentation while maintaining security through automatic escaping.
How do I render a template in Django?
In Django, render a template using the render() function in your views. The code syntax looks as follows: return render(request, ‘template.html’, {‘context’: data}).
How can I secure my Django templates?
Django templates are automatically XSS-protected through HTML escaping. To improve security, yse {% csrf_token %} in forms for CSRF protection, avoid {{ var|safe }} unless necessary, and keep sensitive data out of template context. Also, use template inheritance wisely and never pass untrusted user input directly to templates.