When learning Django Web development, the template engine is a key tool for rendering backend data into web pages. Django natively uses Jinja2 as its template engine, which allows us to “inject” data passed from the view into HTML templates with a concise syntax. Today, we’ll focus on the most commonly used variables and loop syntax in Jinja2 to help you quickly get started with template rendering.
I. What is the Jinja2 Template Engine?¶
In simple terms, a template engine combines backend data (such as user information, lists, dictionaries, etc.) with HTML templates to generate the final web page displayed to the user. For example, if the backend has a variable user_name = "Xiaoming", the template engine will replace {{ user_name }} with “Xiaoming” and display it on the webpage.
II. Variable Syntax: Inserting Data into Templates¶
In Jinja2, variables are wrapped in double curly braces {{ }} to fetch and display data from the backend view.
1. Basic Variable Usage¶
Suppose we prepare data in the view function and pass it to the template. For example:
# Example view function (views.py)
from django.shortcuts import render
def index(request):
# Pass different types of data to the template
context = {
"name": "Xiaoming", # String variable
"age": 20, # Numeric variable
"is_student": True, # Boolean variable
"hobbies": ["Basketball", "Coding", "Music"] # List variable
}
return render(request, "index.html", context)
Then in the template file index.html, we can use the variables as follows:
<!-- Example index.html -->
<!DOCTYPE html>
<html>
<head><title>My Information</title></head>
<body>
<!-- Display string variable -->
<p>Name: {{ name }}</p>
<!-- Display numeric variable -->
<p>Age: {{ age }} years old</p>
<!-- Display boolean variable (automatically converted to text) -->
<p>Is Student: {{ is_student }}</p>
<!-- Display list variable (requires looping, covered later) -->
<p>Hobbies: {{ hobbies }}</p> <!-- Directly display the list -->
</body>
</html>
After rendering, the webpage will show:
Name: Xiaoming
Age: 20 years old
Is Student: True
Hobbies: ['Basketball', 'Coding', 'Music']
2. Complex Data Types: Dictionaries and Nested Structures¶
If a dictionary is passed, Jinja2 supports two access methods: dot notation (.) or square brackets ([]). For example, the view passes:
context = {
"user": {
"name": "Xiaohong",
"age": 18,
"address": {"city": "Beijing", "district": "Haidian District"}
}
}
Usage in the template:
<!-- Access dictionary key-value pairs -->
<p>User Name: {{ user.name }}</p> <!-- Dot notation -->
<p>User City: {{ user["address"]["city"] }}</p> <!-- Nested square brackets -->
Rendering result:
User Name: Xiaohong
User City: Beijing
3. Important Notes¶
- Undefined Variables Cause Errors: If a variable used in the template is not passed in the view (e.g.,
{{ email }}butemailis not incontext), Jinja2 will throw anUndefinedError. You can use{% if variable %}to check existence or thedefaultfilter (mentioned briefly later). - No Direct Modification: Templates are “read-only”; variables cannot be modified directly in the template (e.g.,
{{ age = age + 1 }}is invalid). Variables can only be passed from the view or transformed via filters.
III. Loop Syntax: Batch Displaying List/Dictionary Data¶
When displaying multiple items (e.g., lists or list-of-dictionaries), Jinja2 provides the {% for %} loop syntax, ending with {% endfor %}.
1. Basic Loop Example¶
Suppose the view passes a hobbies list:
context = {"hobbies": ["Basketball", "Coding", "Music"]}
Loop through and display in the template:
<h3>My Hobbies:</h3>
<ul>
{% for hobby in hobbies %} <!-- "hobbies" is the list passed from the view -->
<li>{{ hobby }}</li> <!-- Output each hobby in the loop -->
{% endfor %} <!-- End the loop -->
</ul>
After rendering, the webpage will show:
My Hobbies:
- Basketball
- Coding
- Music
2. Special Loop Variable: forloop¶
During looping, Jinja2 automatically creates the forloop variable, which contains additional loop information. Common uses:
- forloop.counter: Counting starting from 1 (e.g., 1st, 2nd, …)
- forloop.counter0: Counting starting from 0
- forloop.first: Boolean indicating if it’s the first element
- forloop.last: Boolean indicating if it’s the last element
Example: Add serial numbers and mark the first/last items:
<ul>
{% for hobby in hobbies %}
<li>
Serial: {{ forloop.counter }} <!-- Count (1, 2, 3...) -->
- {{ hobby }}
{% if forloop.first %} <!-- Highlight the first element -->
<span style="color: red;">(Favorite Hobby)</span>
{% endif %}
</li>
{% endfor %}
</ul>
Rendering result (for a 3-item list):
- Basketball (Favorite Hobby)
- Coding
- Music
3. Handling Empty Lists: {% empty %}¶
If the list is empty, the loop will skip rendering. Use {% empty %} to show a default message:
<ul>
{% for hobby in hobbies %}
<li>{{ hobby }}</li>
{% empty %} <!-- Executes when the list is empty -->
<li>No hobbies data available</li>
{% endfor %}
</ul>
4. Looping Through a List of Dictionaries¶
To loop through a list of dictionaries (e.g., multiple user profiles):
context = {
"users": [
{"name": "Xiaohong", "age": 18},
{"name": "Xiaogang", "age": 22},
{"name": "Xiaoli", "age": 20}
]
}
Template loop:
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}
</table>
IV. Summary¶
Jinja2 variables and loops are core to template rendering. Mastering them lets you easily display backend data on web pages:
- Variables: Use {{ variable }} to display strings, numbers, dictionaries, etc.
- Loops: Use {% for variable in list %} to iterate over data, with forloop for counting/first/last checks, and {% empty %} for empty lists.
The syntax might seem a bit unfamiliar at first, but practice will make it second nature. We’ll cover advanced topics like conditionals and filters in future articles—start by mastering variables and loops!