The Django Template Language is a special syntax for use inside of HTML files to be used by the Django Web Framework. DTL is an enhanced form of HTML that makes use of standard HTML syntax combined with the Django Specific template language so that variable data can be dynamically injected into the template creating a dynamic HTML page. This page is then returned with the HttpResponse to the client for display in the browser. DTL also offers constructs for conditional checking and looping that we will investigate as well.
The context Dictionary
To begin making your pages dynamic in Django, you need to become familiar with the concept of the context dictionary. This is the optional third argument to the render() function in Django. In the context dictionary will be key / value pairs that are passed to the template being rendered as variables. Each key becomes the variable name in the template, and you can access the value in the template by referencing the key name. The snippet below populates the context variable with some dynamic data.
C:\python\djangoprojects\myproject\goals\views.py
from django.shortcuts import redirect, render
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
# dictionary data store
goals = {
'daily': 'Learn Something New',
'weekly': 'Take a day off',
'monthly': 'Complete a creative course'
}
def homepage(request):
goal_list = '<html><body><ul>'
for goal in goals.keys():
href = reverse('namedurl', args=[goal])
goal_list += f'<li><a href="{href}">{goal}</a></li>'
goal_list += '</ul></body></html>'
return HttpResponse(goal_list)
def goals_by_int_timeframe(request, timeframe):
timeframes = list(goals.keys())
redirect_to = timeframes[timeframe - 1]
named_redirect = reverse('namedurl', args=[redirect_to])
return HttpResponseRedirect(named_redirect)
def goals_by_timeframe(request, timeframe):
context = {'goal': goals[timeframe]}
return render(request, 'goals/goal.html', context=context)
Using Context Variables In Templates
Variables in Django Templates are referenced using the special syntax of two curly braces, followed by the variable name, followed by two additional curly braces. It looks like this:
- {{ variable }}
This is not standard HTML but is picked up by Django as it parses and evaluates the template file. When the template engine finds a variable, it evaluates that variable and replaces it with the value contained in the context. Variable names can be any combination of alphanumeric characters and the underscore (“_”) but may not start with an underscore, and may not be a number. You also cannot have spaces or punctuation characters in variable names.
In looking at this line of code from the view function in question:
goals\templates\goals\goal.html
context = {'goal': goals[timeframe]}
We should understand that ‘goal’ is now a variable that can be accessed in the template. Let’s try that out!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{ goal }}</h1>
</body>
</html>
The result is that we now have dynamic data getting loaded into the template for each page view. Excellent!
We can look at the source of the page in the web browser and notice that those specific curly braces are not there. Instead, it appears as if the value on the page is hardcoded. This is because Django analyzed and replaced any curly braces on the fly during rendering on the server. This is then packaged up as the final HTML string to be sent with the HttpResponse to the web browser. The web browser only receives the final HTML code markup, therefore you will never see any Django Template Language-specific syntax when viewing the web browser page source. Being able to inject dynamic values is one of the key features of the Django Template Language.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Learn Something New</h1>
</body>
</html>
More Than One Variable
Dynamic web pages in Django will surely make use of more than one variable. Since the context dictionary can have as many key/value pairs as you like, it is easy to add additional variable values to be evaluated in the template. Here we modify both the view function and the template to reflect more than one dynamic value for the template.
goals\views.py
def goals_by_timeframe(request, timeframe):
context = {
'goal': goals[timeframe],
'timeframe': timeframe
}
return render(request, 'goals/goal.html', context=context)
goals\templates\goals\goal.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{ timeframe }} goal</h1>
<h2>{{ goal }}</h2>
</body>
</html>