模板层 Template
模板层的作用,是把后端数据渲染成用户能够看到的网页内容。
如果没有模板,你当然也可以在视图里直接拼 HTML 字符串,但那样会非常难维护。页面越复杂,代码就越混乱。
模板存在的意义就是:
- 让 HTML 结构和 Python 逻辑分开
- 让页面可以根据后端传来的数据动态变化
本节目标
- 理解模板层的作用
- 学会使用
render()渲染页面 - 理解上下文变量
- 学会模板变量、条件、循环
- 学会模板继承和复用
- 学会使用常见过滤器
- 建立“页面模板化”的基本意识
为什么需要模板
先看一种不推荐但很直观的写法:
from django.http import HttpResponse
def home(request):
return HttpResponse("<h1>欢迎学习 Django</h1>")这在极简单场景下能跑,但问题很明显:
- HTML 写在 Python 字符串里,不好看
- 页面一复杂就很难维护
- 不能优雅复用页头、页脚、导航栏
所以正式开发里,通常会把页面写在模板文件里,再让 Django 把数据填进去。
最基础的模板渲染
视图:
from django.shortcuts import render
def home(request):
return render(request, "home.html")模板 home.html:
<h1>欢迎来到 Python 学习空间</h1>
<p>这里是首页内容。</p>访问这个页面后,浏览器看到的就是模板里的 HTML 结构。
render() 到底做了什么
render(request, "home.html")你可以把它理解成:
- 找到模板文件
- 把模板渲染成最终 HTML
- 返回给浏览器
所以 render() 是 Django 模板层最常见的入口。
上下文变量是什么
很多时候,页面内容不是固定死的,而是来自后端数据。
例如:
- 当前用户名
- 文章标题
- 课程列表
- 搜索结果
这时就需要把数据从视图传给模板。
视图:
from django.shortcuts import render
def profile(request):
context = {
"name": "小明",
"age": 18
}
return render(request, "profile.html", context)模板:
<h1>{{ name }}</h1>
<p>年龄:{{ age }}</p>页面最终显示:
小明
年龄:18这里的 context 就是上下文数据。
模板变量
模板变量最常见的写法是:
{{ name }}它表示:把视图传来的变量值显示到页面上。
字典取值
如果传来的数据是字典:
return render(request, "user.html", {
"user": {
"name": "小明",
"city": "上海"
}
})模板可以这样写:
<p>{{ user.name }}</p>
<p>{{ user.city }}</p>模板条件判断
模板中可以写简单逻辑。
{% if score >= 60 %}
<p>及格</p>
{% else %}
<p>不及格</p>
{% endif %}如果 score 是 80,页面显示:
及格如果 score 是 50,页面显示:
不及格为什么模板里要有条件判断
因为页面展示经常要根据数据状态变化,例如:
- 用户是否登录
- 是否有搜索结果
- 订单是否支付
模板循环
模板里经常要把列表数据一项一项渲染出来。
视图:
from django.shortcuts import render
def student_list(request):
students = ["小明", "小红", "小刚"]
return render(request, "student_list.html", {
"students": students
})模板:
<h1>学员列表</h1>
{% for item in students %}
<p>{{ item }}</p>
{% endfor %}页面显示:
学员列表
小明
小红
小刚模板里渲染表格
前面学循环时,你已经可以把列表逐条输出。现在看一个更实际的表格例子。
视图:
from django.shortcuts import render
def course_list(request):
courses = [
{"name": "Python 基础", "level": "入门"},
{"name": "Django 开发", "level": "进阶"},
{"name": "Scrapy 爬虫", "level": "进阶"}
]
return render(request, "course_list.html", {
"courses": courses
})模板:
<table border="1">
<tr>
<th>课程名称</th>
<th>难度</th>
</tr>
{% for item in courses %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.level }}</td>
</tr>
{% endfor %}
</table>这样页面就能根据后端数据动态生成表格。
模板继承
这是模板层非常重要的能力。
为什么需要它?
因为一个网站通常很多页面都有共通部分,例如:
- 页头
- 导航栏
- 页脚
如果每个页面都重复写,会非常低效。
父模板
base.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
<h1>Python 学习空间</h1>
<hr>
{% block content %}
{% endblock %}
</body>
</html>子模板
home.html:
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<p>这里是首页内容。</p>
{% endblock %}这样:
- 公共结构只写一次
- 子页面只关心自己不同的部分
这就是模板继承的核心意义。
模板包含
除了继承,你还可以拆出可复用小片段。
例如把导航栏单独写成:
nav.html
<nav>
<a href="/">首页</a>
<a href="/course/">课程</a>
</nav>然后在其他模板中引入:
{% include "nav.html" %}这也是模板复用的一种方式。
过滤器
过滤器可以在模板里对变量做一些简单处理。
大写
{{ name|upper }}默认值
{{ nickname|default:"未设置昵称" }}长度
{{ students|length }}如果 students 列表有 3 项,页面就会显示:
3过滤器的意义是:把一些简单展示处理放在模板层完成,而不是每次都在视图里先处理一遍。
模板标签和变量的区别
变量
用于输出数据:
{{ name }}标签
用于控制逻辑:
{% if %}
{% for %}
{% block %}
{% include %}简单记忆:
负责显示内容{% %}负责控制逻辑
一个完整小案例:课程列表页
视图:
from django.shortcuts import render
def course_page(request):
courses = [
{"name": "Python 基础", "teacher": "张老师", "is_hot": True},
{"name": "Linux 入门", "teacher": "李老师", "is_hot": False},
{"name": "Django 开发", "teacher": "王老师", "is_hot": True},
]
return render(request, "course_page.html", {
"courses": courses
})模板:
<h1>课程列表</h1>
{% for item in courses %}
<div>
<h3>{{ item.name }}</h3>
<p>讲师:{{ item.teacher }}</p>
{% if item.is_hot %}
<p>状态:热门课程</p>
{% else %}
<p>状态:普通课程</p>
{% endif %}
</div>
<hr>
{% endfor %}这个例子已经把模板最常见的三个能力串起来了:
- 变量输出
- 循环
- 条件判断
常见错误
1. 变量名传错
视图里传的是:
{"name": "小明"}模板里却写:
{{ username }}那页面当然取不到值。
2. 模板标签没闭合
例如:
{% if score > 60 %}
<p>及格</p>少了:
{% endif %}3. 把复杂业务逻辑硬塞进模板
模板应该负责展示,不应该承担太复杂的数据处理逻辑。复杂逻辑应尽量留在视图或模型层。
4. 父模板和子模板的 block 对不上
如果父模板定义的是:
{% block content %}{% endblock %}子模板却写成别的名字,就不会生效。
练习题
练习 1
写一个模板页面,显示你的昵称和学习方向。
练习 2
传一个学员列表到模板中,用循环逐项输出。
练习 3
传一个成绩到模板里,用条件语句判断“及格”或“不及格”。
练习 4
写一个父模板 base.html,再写一个子模板 home.html 继承它。
练习 5
尝试使用 upper、default、length 这几个过滤器做简单练习。
本节小结
模板层的核心意义,是把页面结构和 Python 逻辑分开,并让页面能够根据后端数据动态变化。
你这一节最重要的收获应该是:
- 会用
render()返回模板页面 - 理解上下文变量
- 会用变量、条件和循环渲染页面
- 理解模板继承和复用
- 会用简单过滤器处理显示效果
只要模板这一层打牢,后面你做 Django 页面就不再只是“返回字符串”,而是真正开始做网站页面。