7 How to Write Better Django Templates


The goal of these template improvements is to allow us to write templates that are structures well and are more reusable so as to be able to reduce code duplication as much as possible.

Let’s start firstly by creating the home.html template in the same folder as the login.html template and rendering it in accounts/views.py instead of the login.html template:

    return render(request, 'accounts/home.html', args)

There’s no need to delete the login.html template because we can use that later to render the login form itself. For now, it just makes more sense to have the home view render the home.html template to render what is essentially the home page.

Let’s also create a new file in the parent directory of the current templates called accounts/templates/base.html. This will hold all the HTML for everything that we want to look consistent through more than one template (or even our entire site as necessary). This can eliminate a vast amount of superfluous, duplicated code in the other templates.

To be able to use that base.html template when the home.html template is rendered (like in the home view), it needs to be “extended”. In home.html:


{% extends 'base.html' %}

<h1>Home</h1>

In the newly created accounts/templates/base.html:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet"
            href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
            integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
            crossorigin="anonymous">
        {% block head %}
        <title></title>
        {% endblock %}
    </head>
    <body>
        <h1>Base</h1>
        {% block body %}
        {% endblock %}
    </body>
</html>

Now again in home.html we can further utilise the base.html template from which it extends:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
        <title>Home</title>
        {% endblock %}
    </head>
    <body>
        {% block body %}
        <h1>Home</h1>
        {% endblock %}
    </body>
</html>

Any block tags defined in the home.html template will completely replace the contents of the ones defined inside the base.html template. You should notice now that even though the view is rendering home.html (without a link to the Bootstrap CDN), it still has access to it because that was defined explicitly above {% block head %} in the base.html template. If it was instead inside the head block, it would not be linked in the home.html template as the head block in that template takes precedence.