Django Templates – The Comprehensive Reference Guide

Django Templates

Continuing on from our Django tutorial series, let’s understand Django templates. For making a web application, you would need both the front end and the back end.

It will be quite confusing if we mix these both. Django provides us with a very powerful way to keep the HTML/CSS front end codes completely separate from the Back-end code.


DTL – Django Template Language

Using Django Templates, a Front-end developer does not need to learn python and a back-end programmer doesn’t need to know HTML.

A Front end developer can simply leave HTML comments(wherever he wants DB and other information from Django). Later a programmer can simply replace them with a Template language – known as the Django Templates Language (DTL)

Thus DTL is one of the template languages used to embed Django/python codes in HTML files.

DTL has an advantage over others due to its

  • Simplicity
  • Easy to learn the syntax
  • extensible

Basic Syntax of the Django Template Language (DTL)

DTL syntax is similar to python and is very easy to learn. It is further divided into 3 types

1. Template tags

These template tags do something. This sentence might be hard to understand but you will get an idea after seeing the examples, so don’t worry !!

Note : A template tag is enclosed by {% and %}. Some examples are:

  • Condition statements/Display logic –> {% if %} … {% endif %}
  • Loops –> {% for x in y %} … {% endfor %}
  • Block Declaration –> {% block content %} … {% endblock %}
  • Content import –> {% include “header.html” %}
  • Inheritance –> {% extends “base.html” %}

2. Template variables

Template variables are similar to the variable used in python.

Note: The syntax used is {{ and }} Some examples are:

  • Simple variable –> {{ title }} , {{ x }}
  • List attributes –> {{ fruits_list.0 }}
  • Object attributes –> {{ name.title }}
  • Dictionary attribute –> {{ dict.key }}

Note: Here, list.0 is used unlike list[0] in python to access first element of a Python list


3. Template Filter

A template filter is used for filtering the variables/attributes.

Note: The symbol | (pipe) is used for indicating filters.

Some examples are:

  1. Changing cases –> {{ name|title }} or {{ characters|upper_case }}
  2. List filters/slicing –> {{ list|slice = “ :5 “ }}
    This means that from the list, show only the first 5 elements.
  3. Truncation –> {{ name|truncatewords : 80 }}
    This means that from the name, show only first 80, i.e., truncate the name to the first 80 characters.
  4. Default –> {{ value|default =”0” }}
    This means that shows a default value of 0 if variable value is empty.

1. Creating a Django Templates Folder

In Django, since we are keeping all the front end files separate from the back-end, these Text files (mostly HTML files) are also kept in a separate folder.

Template Setting
Template settings.py

Now if we go to the settings.py, there will a TEMPLATES option as shown above. Now the important thing here is the APP_DIRS

'APP_DIRS':True

What this line means is that Django will search for templates/HTML files in a folder called templates.

That means we have to make a templates folder in our Django app and save all the HTML files there.

Templates Folder
Templates Folder

2. Namespacing the Template

When we load a particular template file, Django goes through each app listed in the INSTALLED_APPS in the settings.py. It does so in a top to bottom order and loads the first file it gets with that name. 

We might have more than one app in our project, and also there can be two HTML files with the same name in more than one app.

Suppose you have a Books app and a Pens app. Both have an index.html file in their templates folder.

If you try to include index.html in your views.py for the Books app, Django might end up loading the wrong index.html file.

This happens because, as mentioned earlier, it loads the first instance of the file from the INSTALLED_APPS list.

And it can lead to problems. To avoid this, we use namespacing in the template folders.

What I mean by that is to add another folder with the app name inside the template folder.

Namespacing
Namespacing

In my case, the app is named “books _website“, so I will namespace the templates folder with that name (as shown in the screenshot above).

Thus, when you include the file in your views.py, you will write the include path as

 “ <app_name>/<HTML file>”

That is, in my case, it will be

‘books_website/index.html’ 

The naming convention can be changed as required and doesn’t need to be the app name.

However, it’s a standard practice to use app names for convenience.

3. Creating a Basic DTL File

Now let us make a simple template file and learn how to include it in our views.py. In templates/books_website folder of the app, add a bookView.html file:

Books Website Books
books_website/BookView.html

Now add the code into the file:

{% for book in books %}
    <li>{{book.title}}</li><br>
{% endfor %}
BookView.html
BookView.html

The code is self-explanatory as it is a general for loop to print the list of books.

4. Rendering templates in views.py 

The most efficient way to send model information into template files is by using the function render in views.py.

render(request,<html file path>,<context>)

The render method takes the context(which is the model information), sends it to the template using its path, and then returns the appropriate response for the browser.

In views.py, write the code in BookView:

def BookView(request):
    books = BookModel.objects.all()
    context = {
        'books':books
    }
    return render(request,'books_website/BookView.html', context)
BookView
BookView

Here:

  • we stored Model data into books
  • Note: we created a context as a dictionary
  • we called the render function which took request, template path, and context as its argument and returns back the appropriate response.

Now lets run the server and check the browser

Browser
Browser

5. Template inheritance

Now in BookView.html, we had a small HTML snippet but in reality, HTML files are usually long.

Since most web pages of a website are the same with some modifications in the content, Django provides a method called Template Inheritance. This avoids the need to repeat the code and add unnecessary redundancy to it.

Another benefit of template inheritance is the ability to modify the main file of code so the UI/HTML changes reflect for the entire application.

Thus we create basic HTML files that have the complete code frame that’s common between all the pages.

We store this file in a template folder outside the apps (in the project) so that every Django app can access them.

To inherit the code within other templates, add this line to TEMPLATES in settings.py.

'DIRS': [os.path.join(BASE_DIR,'django_project/templates')],

This line is easy to understand:

  • We get the base Django directory using the pre-defined variable BASE_DIR (Our Django project folder)
  • Then with the os module, we join it to the django_project/templates line.

Read the above para properly and more than once to understand what we are trying to do.

Basic Html
Base HTML path

Now lets us make a simple basic.html file, which adds “Hello Viewer” to all its webpages.

The syntax used to write the file is:

<h2>Hello Viewer</h2>
{% block content %}
    <p> PlaceHolder to be Replaced</p>
{% endblock %} 

In the basic file, we add a block (with a name “content” in my case) and then add a default line in case an error occurs while loading the other HTML file.

That default line will be replaced with the content present in the HTML file inside the app.

Basic.html
Basic.html

Now let us change the BookView.html file to incorporate basic.html file.

Write the code below into the file

{% extends 'basic.html' %}

{% block content %}
    {% for book in books %}
        <li>{{book.title}}</li><br>
    {% endfor %}
{% endblock %}

  • We add a line {% extends ‘basic.html’ %} in the starting to inherit the Parent file(basic.html)

In order to indicate Django, that the block ( name – content) present in basic.html file is to be replaced, we add a block with the same name (that we used in the basic.html file).

Inside that block, we write the code which will replace the default line

BookView.html
BookView.html

Now lets run the server and check the browser

Browser Inheritance
Browser Inheritance

6. Template inclusion

Similar to Inheritance, Django Template Files can also be included in other HTML files.

Let us make another file BookViewAdd.html which adds a heading “Books Hub” and let’s include it into BookView.html

Create another HTML file by the name(BookViewAdd) into books_website/templates folder and just add the line

<h3>Book Hub</h3>
BookViewAdd
BookViewAdd

Now in the BookView.html, inside the block content add the inclusion code line:

{% extends 'basic.html' %}

{% block content %}
    {% include 'books_website/BookViewAdd.html' %}
    {% for book in books %}
        <li>{{book.title}}</li><br>
    {% endfor %}
{% endblock %}

Here we used {% include ‘books_website/BookViewAdd.html’ %} which is similar to the inheritance syntax that we used earlier.

BookView Inclusion
BookView Inclusion

Now lets run the server and check the browser

Browser
Browser

Conclusion 

That’s all for the Django templates tutorial! We hope you have a solid understanding of the template functionality in Django. Also, you can learn more about the Django Template language we used here from the official documentation.

Stay tuned for more advanced tutorials on Django topics!