很多刚学习 Django 的开发者都会产生一个错觉:
模板层只是 HTML + {{变量}}
实际上,在真实项目中,模板层承担着大量工作:
- 页面逻辑控制
- 数据循环渲染
- 表单状态保持
- 组件复用
如果没有理解 Django 模板机制,很容易写出 难维护甚至错误的页面逻辑。
这篇文章我们系统梳理 Django 模板层最核心的内容。
文章目录
- Django 模板层在 MTV 架构中的作用
- View 如何向 Template 传递变量
- Django 模板支持哪些数据结构
- 模板变量调用规则(重点)
- Django 模板标签语法
- if 标签详解
- for 标签与 empty 用法
- forloop 内置变量详解
- 实战案例:Django 计算器
- Django 模板开发常见坑
- Django 模板的重要补充知识
一、Django 模板层在 MTV 架构中的作用
Django 使用 MTV 架构:
- Model:数据层
- Template:视图展示层
- View:业务逻辑层
请求流程如下:
flowchart LR
A[浏览器请求] --> B[URL路由]
B --> C[View视图函数]
C --> D[业务逻辑处理]
D --> E[render传递数据]
E --> F[Template模板]
F --> G[HTML页面]
G --> H[浏览器渲染]
简单理解:
View 负责数据处理 Template 负责页面渲染
两者之间通过 变量字典进行通信。
二、View 如何向 Template 传递变量
Django 最常见写法:
def index(request):
context = {
"name": "Tom",
"age": 18
}
return render(request, "index.html", context)
render 函数结构:
render(request, template_name, context)
第三个参数 context 是一个字典。
模板中可以通过:
{{ name }}
访问数据。
三、Django 模板支持哪些数据结构
Django 模板可以接收 绝大多数 Python 对象:
1 字符串 2 整数 3 list 4 tuple 5 字典 6 函数 7 类实例对象 8 QuerySet
示例:
def test(request):
data = {
"name": "Tom",
"age": 20,
"hobby": ["coding", "game"],
"info": {"city": "Beijing"},
"func": test_func
}
return render(request, "test.html", data)
注意一点:
如果传递函数
正确:
"func": test_func
错误:
"func": test_func()
后者传递的是 函数执行结果。
四、模板变量调用规则(重点)
模板中变量语法:
{{ variable }}
示例:
<p>{{ name }}</p>
<p>{{ age }}</p>
Django 模板点查找规则
Django 使用 统一的点查找机制:
{{ object.attribute }}
查找顺序:
1 字典 key 2 对象属性 3 方法调用 4 列表索引
例如:
data = {
"user": user,
"list": ["A", "B"]
}
模板:
{{ user.name }}
{{ list.0 }}
模板方法调用规则
模板可以调用方法:
{{ user.get_full_name }}
但 Django 模板 只允许调用无参数方法。
这是出于 安全性设计。
五、Django 模板标签语法
模板标签用于 逻辑控制。
语法:
{% 标签 %}
结束标签:
{% end标签 %}
示例:
{% if %}
{% endif %}
六、if 标签详解
基本语法:
{% if age > 18 %}
成年人
{% else %}
未成年
{% endif %}
支持的操作符:
- ==
- !=
-
- <
-
=
- <=
- and
- or
- not
注意:
Django 模板 不支持复杂括号表达式。
七、for 标签与 empty 用法
循环结构:
{% for item in list %}
{{ item }}
{% endfor %}
empty 标签
当列表为空时:
{% for item in list %}
{{ item }}
{% empty %}
暂无数据
{% endfor %}
这个设计比 Python 更方便。
八、forloop 内置变量详解
for 循环中 Django 提供一个特殊变量:
forloop
常用属性:
| 变量 | 含义 |
|---|---|
| forloop.counter | 从1开始 |
| forloop.counter0 | 从0开始 |
| forloop.revcounter | 倒序索引 |
| forloop.first | 是否第一次 |
| forloop.last | 是否最后一次 |
示例:
{% for name in names %}
{{ forloop.counter }} {{ name }}
{% endfor %}
九、实战案例:Django 计算器
页面结构:
- 输入数字A
- 运算符选择
- 输入数字B
- 点击计算
流程如下:
flowchart TD
A[输入数字A] --> D[提交表单]
B[选择运算符] --> D
C[输入数字B] --> D
D --> E[POST请求]
E --> F[Django视图]
F --> G[计算结果]
G --> H[返回模板]
View 代码
def mycal(request):
result = None
n1 = None
n2 = None
op = None
if request.method == "POST":
n1 = request.POST.get("n1")
n2 = request.POST.get("n2")
op = request.POST.get("op")
try:
n1 = int(n1)
n2 = int(n2)
if op == "+":
result = n1 + n2
elif op == "-":
result = n1 - n2
except:
result = "输入错误"
return render(request, "cal.html", locals())
locals() 会把函数中的变量打包成字典。
十、表单状态保持
当页面刷新时,用户的选择容易丢失。
可以这样写:
<option value="+" {% if op == "+" %} selected {% endif %}>
+
</option>
这样提交后仍然保持用户选择。
十一、Django 模板重要补充知识
这里补充三个很多教程不会讲的关键点。
1 模板过滤器
过滤器用于处理变量。
语法:
{{ value | filter }}
示例:
{{ name | upper }}
常用过滤器:
| 过滤器 | 作用 |
|---|---|
| upper | 大写 |
| lower | 小写 |
| length | 长度 |
| default | 默认值 |
示例:
{{ username|default:"匿名用户" }}
2 模板自动转义
Django 默认开启 XSS 防护。
示例:
<script>alert(1)</script>
模板输出:
<script>
如果需要关闭:
{{ content|safe }}
3 模板继承
大型项目都会使用模板继承:
{% extends "base.html" %}
然后定义块:
{% block content %}
页面内容
{% endblock %}
这样可以实现 统一页面布局管理。
结语
Django 模板系统虽然语法简单,但设计非常成熟。
核心能力包括:
1 变量传递 2 模板逻辑控制 3 数据循环 4 页面状态保持 5 模板继承与组件化
理解这些机制后,你会发现:
Django 模板不仅是 HTML 模板,而是一个完整的 视图渲染系统。