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
<!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
{% 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
{% block index %} 子模板会替换父模板block index中的内容 {% endblock %}
1
{% 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
{% 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
<!DOCTYPE html>
<html>
  <head>
    {% block title %}{% endblock %}
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
  <%block name="js"> {% endblock %} ${next.body()}
</html>

4. 参考


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