一、模板层简介
-
模板简介
动态生成模板HTML方便,包括HTML静态部分的输出和一些特殊语法的动态插入内容。
Django后端内置一个自己的模板系统,称为Django template language(DTL)。第三方提供的模板引擎也可用于后端。最受欢迎的是jinja2引擎。
-
简单用法:
使用
render(request, '模板.html', 字典)渲染模板的方法是以字典的形式将变量传递给模板进行替换。例如,在视图中:
render(request, 'index.html', { 'name': 'hugh'})在变量大的情况下,可以,简化步骤。
render(request, 'index.html',locals())。然后在模板中:
<h1>My name is { { name }}!</h1>这样,就会My name is hugh!在网页上以标题样式显示。
二、变量
当模板引擎遇到变量时,它会计算变量并将其替换为结果。
变量名由字母、数字和下划线组成,但,也不能是数字。
-
基本语法:
输出上下文中的变量html中。
{ { 变量名 }} -
如果变量传入函数名,则会。但如果函数需要参数,,它不会调用函数,也不会报错,也不会显示任何东西。
-
如果是类名,模板会自动添加
(),调用、实例化、输出__str__方法的返回值。 -
简而言之,对于所有可调用对象,django试着调用模板并替换返回值html中。
-
字典、属性和列表的值只能通过点符号来获得
.实现后跟键、属性名、索引,不能使用[]或get等方法。
三、过滤器
用于修改显示的变量结果的过滤器。
-
基本语法:
{ { 数据|过滤器:参数}}过滤器可以是链式的,过滤器后面可以跟着过滤器。
-
常用过滤器:
统计a长度:{ { a|length }} 设置a的默认值为奇怪False,使用默认值:{ { a|default:'嘤嘤怪' }} 将文件大小file_size,以更人性化的格式输出:{ { file_size|filesizeformat }} 将时间time格式化后输出: { { time|date }} 输出:2067年1月23日 { { time|date:'Y-m-d H:i:s' }} 输出:2067-01-23 10:32:09 从0到4(不0到4(不包括4),步长为2:{ { s|slice'0:4:2' }} 从s中截取10个字符,包括最后三点:{ { s|truncatechars:10 }} 输出:写点什么... 从s中截取5个单词,不包括最后三点:{ { s|truncatewords:5 }} 输出:随 便 写 点 什... 移除s中的字符*:{ { s|cut:'*'}} 使用$L元素拼接列表:{ { l|join:'$' }} python的 运算符:{ { i|add:10 }}或{ { s|add:'abc' }} 将字符串ele='<h1>嘿嘿嘿</h1>按照html渲染,而不是通字符串:{ { ele|safe }} 取消转义,按字符串直接输出‘<h1>嘿嘿嘿</h1>':{ { ele }}
四、标签
标签(不是指html在渲染过程中提供任何逻辑。可以是任何内容,也可以是if、for等句,甚至可以放其他模板句。
-
基本语法:
{% 标签 参数1 参数2 …… %} -
for循环:
{% for i in l %} { { i }} 循环取出的变量 { { forloop }} {% empty %} …… {% endfor %}变量
{ { forloop }}保存循环计数等信息的字典:变量名 描述 forloop.counter循环计数器表示当前循环的索引(从 1开始)。forloop.counter0循环计数器表示当前循环的索引(从 0开始)。forloop.revcounter反向循环计数器(以最后一循环) 1,反向计数)。forloop.revcounter0反向循环计数器(以最后一循环) 0,反向计数)。forloop.first当前循环是第一个循环时,该变量是 True forloop.last当前循环为最后一个循环时,该变量为 True forloop.parentloop在嵌套循环中,指向当前循环的上级循环 。
-
if判断:
{% if xxx %} …… {% elif yyy %} …… {% else %} …… {% endif %} -
with起别名:
{% with aba.abb.aab as a %} { { a }} 在with语句内,可以直接使用a代表那一大串 {% endwith %}
五、自定义过滤器和标签
1. 自定义过滤器
-
第一步:
先在app文件夹中,创建一个
templatetags子文件夹,名称千万不要写错。 -
第二步:
在
templatetags文件夹中,创建一个任意名称的.py文件。 -
第三步:
在
.py文件中,定义过滤器:@register.filter(name='your_filter') # 过滤器名字随便写,不写默认使用下面的函数名 def my_filter(): # 函数名随便写 pass注意:。
-
第四步:
在模板文件中,使用自定义过滤器:
{% load 自定义过滤器所在py文件的文件名 %} { { xxx|过滤器名称:参数 }}
2. 自定义普通标签
-
第一步:
先在app文件夹中,创建一个
templatetags子文件夹,名称千万不要写错。 -
第二步:
在
templatetags文件夹中,创建一个任意名称的.py文件。 -
第三步:
在
.py文件中,定义标签:@register.simple_tag(name='your_tag') # 标签名字随便写,不写默认使用下面的函数名 def my_tag(): # 函数名随便写 pass注意:。
-
第四步:
在模板文件中,使用自定义过滤器:
{% load 自定义标签所在py文件的文件名 %} {% 标签名称 参数 …… %}
六、模板继承
模板继承可以让我们重用部分页面的html代码,减少代码冗余。
比如说,我们的某个网站的所有页面,都有相同的导航条和底栏。于是,我们就可以将导航条和底栏单独写在一个html文件中,比如叫做base.html。在其它所有的页面中,使用模板语法,继承这个文件,达到省去重复写这部分代码的目的。
-
在
base.html中:导航条部分…… {% block content %} {# content是对下面的内容随便起的名字 #} 这一部分内容,被继承之后可以修改 …… {% endblock %} 底栏部分…… -
其他继承
base.html的文件中:{% extends "base.html" %} {% block content %} 这里进行修改,会完全覆盖掉被继承文件的内容 …… {% endblock %} -
注意:
{% block xxx %}可以有多个,但不宜太多。如果不想重写
{% block xxx %}中的内容,而是想用父模板base.html的,可以使用{ { block.super }}变量。{% block xxx %}不仅可以标记html代码,还可以标记css和js代码。
最后的效果就是,每个页面都有相同的导航条和底栏,但各自都可以有不同的content部分。
七、包含标签
加载一个模板,并在当前上下文中进行渲染。这是一种在模板中 “包含” 其他模板的方式。 包含标签会使用另一个模板渲染数据,然后将结果放到当前模板中。
例如, Django 的后台利用自定义模板标签在表单页的底部展示按钮。这些按钮看起来一样,但是连接目标根据被编辑的对象不同而不同。(在后台例子中,即 submit_row 标签。)
{% include "title.html" %}
这样,title.html中的内容就会被渲染到{% include "title.html" %}所在的地方了。
可以使用关键字参数向模板传递额外的上下文:
{% include "name_snippet.html" with 形参1="实参1" 形参2="实参2" %}
自定义包含标签
-
第一步:
先在app文件夹中,创建一个
templatetags子文件夹,名称千万不要写错。 -
第二步:
在
templatetags文件夹中,创建一个任意名称的.py文件。 -
第三步:
在存放模板的
templates文件夹中,创建自己需要的模板文件。 -
第四步:
在
.py文件中,定义包含标签:@register.inclusion_tag('menu.html') def my_itag(): # 函数名随便写 …… return xxx # 会将 xxx 传递给 menu.html进行渲染menu.html便是需要渲染的模板,它在渲染完成后会放回使用了包含标签的模板中。 -
第五步:
在模板文件中,使用自定义过滤器:
{% load 自定义包含标签所在py文件的文件名 %} {% 函数名称 参数 …… %}
上面自定义标签的写法只适用于简单的逻辑,更加复杂的逻辑需要更加复杂的写法,建议直接看文档:传送门