Django 自学笔记兼学习教程第3章第4节——模板继承
点击查看教程总目录
在介绍具体的技术之前,先介绍在什么样的场景中,需要使用这样的技术,我觉得这对于新手理解起来很重要。
一般来说,要渲染一个页面我们就需要新建一个对应的模板,然而一个系统中,多个页面常常会有很多功能相似的内容区域,比如都有头部栏、侧边栏、底部信息栏等等,这样的内容区域是多个页面共有的,如果我们不思考采用新的技术方式,而是把在每个页面都写一遍这种共有内容的代码,不仅是代码重复的问题,而且会导致管理的混乱,比如要修改或者检查等等。
这里我们可以先想想python中是如何解决这个问题的,python代码会将公共使用的代码或者方法写在一个库(常常是一个py文件中),哪些py需要用到这部分内容则“导入”这部分内容。
html模板技术也是在解决这一问题,不过使用的是另一种思路,它会将共有的内容代码做成母版,那些要用到这个代码的则是子版,需要先继承母版,再编写子版对应的功能代码。这一点有点像幻灯片。本文主要参考文档: template-inheritance
1 模板继承介绍
官方介绍如下:
模板继承是Django模板引擎中功能最强大的部分,也是最复杂的部分。
模板继承允许你构建一个基本的“骨架”模板,它包含你网站的所有公共元素,并定义子模板可以覆盖的块(即子模板可以自定义编辑的区域)。
2 “母版”
这里用我之前的代码(本章第一节展示过的)作为示例来讲解下模板继承
首先是background.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>
学生选课管理系统
</title>
</head>
<body>
<div class="main-container">
<div class="main-header">
<div class="main-title">学生选课管理系统</div>
<div class="sub-title">Student Course Management System</div>
{% block welcome_message %}
{% endblock %}
</div>
<div class="login-container">
{% block login_container %}
{% endblock %}
</div>
</div>
</body>
</html>
这个就是我们的母版。
官方文档一般称其为html骨架文档,习惯用base.html
来命名,“子”模板的工作就是用内容填充骨架中的空块。
那么哪些是子模板可以填充的空块呢?
我们观察下上面和普通html语法格格不入的代码块,有两块:
{% block welcome_message %}
{% endblock %}
{% block login_container %}
{% endblock %}
这两块就是子模板可以进行填充的,即子模板可以自定义内容的。
其中block
是块标记,所做的只是告诉模板引擎子模板可以覆盖模板的那些部分。block
后面接的一串字符串是这个块的名字,可以认为是一个辨识用的id,后面子模板会用这个id去标明自己要覆盖哪个。endblock
则是一个没有具体意义的结束符,用于标明block
这个块到这里为止。
3 继承“母版”
母版初步介绍完了,接下来我们看看子版login_home.html
{% extends "user/background.html" %}
{% block login_container %}
<div class="login-kind student-login-button">
<a href="">学生登录</a>
</div>
<div class="login-kind teacher-login-button">
<a href="">教师登录</a>
</div>
{% endblock %}
其中第一行的extends
标签是关键:它告诉模板引擎,这个模板“继承”另一个模板。
注:extends
必须在第一行写。
当模板系统计算这个模板时,它首先定位父模板——在本例中是background.html
。
然后,模板引擎将注意到background.html
中的两个block
块标记,并用子模板的对应block
快内容替换这些块。
上面的例子中,login_home.html
的值,输出可能如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<title>
学生选课管理系统
</title>
</head>
<body>
<div class="main-container">
<div class="main-header">
<div class="main-title">学生选课管理系统</div>
<div class="sub-title">Student Course Management System</div>
</div>
<div class="login-container">
<div class="login-kind student-login-button">
<a href="">学生登录</a>
</div>
<div class="login-kind teacher-login-button">
<a href="">教师登录</a>
</div>
</div>
</div>
</body>
</html>
注意,由于子模板没有定义welcome_message
块,所以使用了父模板的值(在上面的例子中是一个空值)。父模板中{% block %}标记内的内容总是用作这样一种场景里的回退。
同时,在子模板中,也可以添加新的block块给下一级子模板使用,即子模板本身也可以作为一个母版。
实际中,可以根据需要使用任意多层的继承级别。