Introduction
In this chapter, you will learn to use Django Templates.
Django Templates
Last time we customized our welcome page but remember, we had to embed the HTML code of the page into the view's Python code. There are a few problems with this approach:
- Good software engineering practices always emphasize the separation between UI and business logic, because it enhances reusability. However, embedding HTML within Python code clearly violates this rule.
- Editing HTML embedded within Python requires Python knowledge, but this is impractical for many development teams whose web designers do not know Python.
- Handling HTML code within Python code is a tedious and error-prone task. For example, quotation marks in HTML may need to be escaped in Python string literals, and the overall result may be unclean and unreadable code.
We’re going to separate our HTML code from Django's views. Django provides a component that will help us accomplish this task; it is called the template system. Let’s apply it to our welcome page and see how it works.
First of all, create a separate folder called template in your project folder. This is just to keep our directory structure clean. A fun thing is if you’re using Pycharm then you can see this templates folder already created for you. It’s just not created but also its path is already added in settings.py. If you’re creating your own template folder then you need to inform Django about it. Open settings.py, look for the TEMPLATE_DIRS variable and add the absolute path of your template folder to it. Or if you don’t want to hard-code the path into settings.py then use the following code.
- import os.path
- TEMPLATE_DIRS = (
- os.path.join(os.path.dirname(__file__), ‘templates’),
- )
What it simply does is that it informs Django where to look for the template. Now, let’s move to our HTML part. Create a file called index.html in the template folder and edit it with the following content:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>Welcome Page</title>
- </head>
-
- <body>
- <h2>Hello World</h2>
- <p>Welcome to my first Application in Django</p>
- </body>
-
- </html>
Pretty straightforward HTML code. All it does is display a welcome message without any Python code. Let’s see how to view this template in the view. Edit webapp/views.py file as follow:
- from django.shortcuts import render
- def main_page(request):
- return render(None, 'index.html')
That’s right. All we need is three lines of code. Let's break down the code.
- We imported the render method from Django.shortcut.
- We just defined the view using the main_page as its name and passing request object to it.
- In order to create HTML output from the template, we used the render method. It combines a given template with a given context dictionary and returns an HttpResponse object with that rendered text.
As per the documentation, render function is somewhat like this.
- render(request, template_name, context=None, content_type=None, status=None, using=None)
Required Arguments
request
The request object is used to generate this response. In our case, we are just displaying a static HTML page so we used request=None.
template_name
The full name of a template to use or sequence of template names. If a sequence is given, the first template that exists will be used. We named our template as index.html so we used its name as an argument to our function.
Other arguments are all optional but let me explain them too.
Optional Arguments
context
A dictionary of values to add to the template context. By default, this is an empty dictionary. It means that it won’t make any difference if you call the function with an empty dictionary as render (None, 'index.html', {}) or without it. But if a value in the dictionary is callable, the view will call it just before rendering the template.
content_type
The MIME type to use for the resulting document. Defaults to the value of the DEFAULT_CONTENT_TYPE setting.
status
The status code for the response. Defaults to 200.
using
The NAME of a template engine to use for loading the template.
Enough of the explanation. Now, run the server and you should see the exact screen you saw last time.
And Boom!
Now you have your HTML code separated from python. But that’s the static page. Is that all by Django? What if I want to integrate some variables on the page? Luckily! Django does support variable integration. Variables are surrounded by a pair of curly braces {{ }} like this. Let’s see how it works.
Open your index.html file and replace the code as follows:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <title>{{ head_title }}</title>
- </head>
-
- <body>
- <h1>{{ page_title }}</h1>
- <p>{{ page_body }}</p>
- </body>
-
- </html>
The structure of this template is very similar to the one before. Just a small difference, however; we used the special syntax for variable support to indicate the sections we want to change in our view.
Now, open views.py and edit its content as follow:
- from django.shortcuts import render
- def main_page(request):
- return render(None, 'index.html', {'head_title': 'Welcome Page',
- 'page_title': 'Hello World',
- 'page_body': 'Welcome to my first App in Django.'})
We talked about the render’s optional argument context. In the above code, we just used that argument and loaded the page as per our context.
You can use it to pretty much display anything. For example,
- My first name is {{first_name}} and my last name is {{last_name}}
With a context of {‘first_name’: ‘Mehreen’, ‘last_name’: ‘Tahir’}, this template renders to:
My first name is Mehreen and my last name is Tahir.
Template Tags and Filters
Django comes along the whole template system. The mains of this system are variables and tags. We have seen the variables so let’s talk about the Tags.
Tags
Tags provide arbitrary logic in the rendering process. They are surrounded by {% %} and can be used to output content or as a control structure. As
- {% if today_is_weekend %}
- <p>Welcome to the weekend!</p>
- {% else %}
- <p>Get back to work.</p>
- {% endif %}
Or,
- {% comment %}
- This is a multi-line comment.
- {% endcomment %}
Or,
- {% block %}
- This block text can be overridden by child template. It is what we call template inheritance.
- {% end block %}
It could also be,
You’re going to use this special template tag when dealing with forms. It provides easy-to-use protection against Cross-Site Request Forgeries.
Also,
- {%extends 'template name'%}
- This tag is used to inherit from a base template.
Filters
Filters are an effective way to modify the data before sending it to the template. Like this,
- {% filter lower %}
- This text will appear in all lowercase.
- {% endfilter %}
An upper filter can also be used,
- {% filter upper %}
- This text will appear in all uppercase.
- {% endfilter %}
There are a lot of cool filters like capfirst, pluralize, line breaks, etc. or maybe use something like this.
- {{ value|add:"1" }}
- If value is 2, then the output will be 3.
This is just a glimpse of the powerful tag system of Django. Go ahead and feel free to experiment with it.
Summary
In the next chapter, you will learn more about Django Templates.