Please enable Javascript to view the contents

Django 模板继承

 ·  ☕ 3 分钟

1. 场景

在一个项目中,header、footer等元素经常被重复使用。为了避免,每个页面重写这些元素,同时,在修改时,不用去每个页面修改,需要将公共的部分抽离出来,这就是Django模板继承。

2. Django的复用模板标签

Django内建的复用模板标签主要有,block 、 extends、include

首先我们来看一个例子:

定义一个项目的公共模板base.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>  
<html>  
    <head>  
    <meta charset="UTF-8">  
    {% block title %}
    <title>My Project</title> 
    {% endblock %} 
    </head>  
<body>  
    <h1>My base</h1>  
    {% block content %}{% endblock %}  
    {% block footer %}  
    <p>I am footer</p>  
    {% endblock%}  
</body>  
</html>

利用公共的base.html模板,定义首页index.html

1
2
3
4
5
6
7
8
{% extends "base.html" %}  
{% block title%}
<title>Home Page of My Project</title> 
{% endblock %}  
  
{% block content %}  
<p> Home page content</p>  
{% endblock  %}  

2.1 block

定义:

block定义一个模板块。子模板的block会覆盖父模板同名的block块。如果想要子模块不覆盖父模块的内容,而是新增,可以使用 block.super。

用法:

1
2
3
{% block index %}
     子模板会替换父模板block index中的内容
{% endblock %}
1
2
3
4
{% block index %}
    {{ block.super }} 
    子模板新增的内容
{% endblock %}

2.2 extends

定义:

extends表示的是继承。通常,一个项目会写一个base.html和若干widget.html。项目中的大部分页面,都会继承自base.html。

用法:

extends的参数一般为字符串,也可为变量。注意使用extends时,extends一定要是第一个tag标签,否则不会生效。

1
{% extends 'base.html' %}

定义:

include将其他模板,以插件的形式,直接添加在当前的模板中。

用法:

可带路径、相对路径、使用变量名。

1
{% include 'tools.html' %}

2.3 其他模板标记

  • autoescape 控制模板的自动转义。
1
2
3
{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}
  • load加载标签库。
1
2
{% load staticfiles %}  
<img src="{% static "images/hi.jpg" %}" />  

还可以在自定义标签。比如在INSTALLED_APPS 中添加’django.contrib.humanize’后,可以在模板中使用 load humanize。需要注意的是,load的标签不会被子模板继承。

3. Mako

Mako是一个高性能的Python模板库,它的语法借鉴了很多其他的模板库,如Django、Jinja2等等。同时,Mako不依赖其他Web框架,可以直接用于html的生成。首次编译时,Mako将HTML模板编译成Python文件,大大提高了渲染和生成页面的速度。

Mako

  • <%include>

接受一个文件名称作为参数,引用一个文件。

  • <%def>

定义一个Python函数:

1
2
3
4
5
<%def name="myfunc(x)">
    this is myfunc, x is ${x}
</%def>

${myfunc(7)}
  • <%inherit>

用于模板的继承。

1
<%inherit file="base.html"/>
  • <%call>

用于调用<%def>定义的Python函数。

  • parent

继承链中父模板的名称空间。parent.head(),在index.html子模板中引用父模板的内容。

  • next

继承链中下一个模板的名称空间。next.body() 的位置决定了,子页面不在block的内容,被渲染的位置。也可使用 self.body(),但 self.body() 只渲染最终页面不在block中的内容,不渲染中间继承页面不在block的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>  
<html>  
    <head>  
    {% block title %}{% endblock %} 
    </head>  
<body>  
    {% block content %}{% endblock %}  
</body>
<%block name="js">
{% endblock %}   
${next.body()}
</html>

4. 参考


微信公众号
作者
微信公众号