Django Templates

Templates

Contents

What’s a Template?

Templates are usually HTML files that describe the layout of a website. They can contain {{ variables }}, which are replaced with values once the template is evaluated, {% tags %}, that control the template’s logic.

Before making a template, be sure that you have an app and include it within the INSTALLED_APPS array in the settings.py file as we did here.

Create a Template

To create our first template, we’ll make a folder in the example_app/ directory that we introduced earlier. Next, we’ll add the first_template.html file to it resulting in a file structure that resembles the one below:

example_project/
├── example_project/
│   ├── ...
├── example_app/
│   ├── migrations/
│   ├── templates/
│   │   ├── first_template.html
├── ...

Within the first_template.html, we can now add some simple html code:

<html>
    <body>
        <h1> My First Template </h1>
    </body>
</html>

Next, the template.html needs to be imported into the views.py file that handles the requests and responses. The views.py file should look as follows:

from django.shortcuts import render
from . import templates

def index(request):
    return render(request, 'first_template.html')

Afterwards, the route must be configured in the urls.py file. This will allow the website visitor to see the rendered first_template.html when he opens a specific URL path in his browser:

from django.urls import path
from example_app import views

urlpatterns = [
    ...
    path('', views.index, name='index'),
    ...
]

Finally, run python manage.py runserver in the terminal and open http://127.0.0.1:8000/.

Context

In Django, context allows us to pass data from our view into our template. Why do we need this? Because it makes our website dynamic. In simple terms, it makes sense to adjust the contents and layout of a website to the viewer.

For example, it only makes sense to show the text “You are logged in” if the user is actually logged in. As another example, it only makes sense to show the cookie banner if they haven’t been accepted yet.

So let’s add some context to the views.py file:

from django.shortcuts import render

def index(request):
    context = {
        'header': "hello django!",
        'user_authenticated': True,
    } 
    return render(request, 'first_template.html', context)

Next, we’ll use this context within the template using variables and tags.

Variables

The most basic type of variable syntax is {{ variable_name }} and it is used to display the value of a variable. Consider the example below, where the title variable and the username attribute of the user object are passed into HTML content:

<h1>{{ header }}</h1>

It’s also possible to modify variables using Django’s template filters. For example, if we want to capitalize the first letter of each word in the header, the tile tag could be used as follows:

<h1>{{ header|title }}</h1>

Instead of a variable, such as header in the above example, it’s also possible to have a string, numeric or boolean literal. Below, you can see an example using a string literal:

<h1>{{ "hello world"|title }}</h1>

But wait, there’s more. You can even chain together filters. In example below, title would capitalize the first letter of each word, and slice:"0:5" would remove characters outside the range of [0, 5]:

{{ "hello world"|title|slice:"0:5" }}

The output of this will be Hello.

Tags

Conditions with if and else are also commonly used to include or exclude content. For example, it might be useful to adjust the content of a website based on whether the user is logged in or not:

{% if user_authenticated %}
    <p>Hello! You are logged in.</p>
{% else %}
    <p>Welcome, guest! Please log in.</p>
{% endif %}

Another common one is For loops, which can be used to iterate over a list of items and create content for each. There might be multiple posts in a blog and listing the linked posts could look as follows:

<ul>
    {% for post in blog_posts %}
    <li>
        <a href="/post/{{ post.id }}/">{{ post.title }}</a>
    </li>
    {% endfor %}
</ul>

Template Inheritance

Some elements like the navigation bar and footer will probably appear on all your pages. To avoid adding these elements to each page template, Django let’s us use template inheritance.

The template below, let’s call it parent.html, serves as the parent. This is where you can include all the elements that should be available across all sites, e.g., the navigation bar. We’re not going to create a navigation bar because that would overload the code. Let’s keep it simple and create a minimal parent template:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Parent Title{% endblock %}</title>
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

The {% block ... %} tags you see above define placeholders that can be replaced in the child templates. For Django to know what belongs to the replaceable block, the {% endblock %} must also be included.

Below is the child.html file that inherits from the parent.html above. This inheritance relationship is set by including {% extends 'parent.html' %} in the child.html file.

{% extends 'base.html' %}

{% block title %}Child Title{% endblock %}

This child template only overwrites the title block of the parent. To overwrite the content block, we could simply include content blocks {% block content %} ... {% endblock %}

Have a Question?

Ask on Discord