模板简介
模板是动态生成HTML的便捷方法,包含HTML需输出的静态部分以及动态插入内容的一些特殊语法。
Django后端内置一个自己的模板系统,称为Django template language(DTL)。后端也可以使用第三方提供的模板引擎,最流行的是jinja2引擎。
简单用法:
使用render(request, '模板.html', 字典)
方法来渲染模板,将变量以字典形式传递给模板进行替换。
比如,在视图中:
render(request, 'index.html', {'name': 'hugh'})
在变量很多的情况下,可以使用
locals()
方法,将视图中的局部变量全部以字典形式传递给模板,简化步骤。如:render(request, 'index.html',locals())
。
然后在模板中:
My name is {{ name }}!
这样,就会将“My name is hugh!”以标题样式展现在网页上。
当模板引擎遇到一个变量时,它会计算该变量并将其替换为得到的结果。
变量名由字母、数字和下划线的组成,但不能以下划线开头,也不能是数字。
基本语法:
将上下文中的变量,输出到html中。
{{ 变量名 }}
如果变量传入的是一个函数名,那么会自动调用该函数,并将返回值替换到此。但是如果该函数需要参数,则没有办法通过模板传参,它就不会调用函数,也不会报错,不会显示任何东西。
如果传入的是类名,模板也会自动加()
,进行调用,实例化,输出__str__
方法的返回值。
简而言之,对于所有可调用对象,django模板都会试着调用,并将返回值替换到html中。
字典、属性和列表等的取值,只能通过点符号.
实现,点后面跟键、属性名、索引,不能使用[]
或get
等方法。
过滤器用来修改显示的变量结果。
基本语法:
{{ 数据|过滤器:参数}}
过滤器可以是链式的,一个过滤器后面可以跟着一个过滤器。
常用过滤器:
统计a的长度:{{ a|length }}
设置a的默认值为“嘤嘤怪”,如果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
对s进行切片,从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='嘿嘿嘿
'转移,按照html进行渲染,而不是当作普通的字符串:{{ ele|safe }}
取消转义,直接按照字符串输出'嘿嘿嘿
':{{ 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 |
在嵌套循环中,指向当前循环的上级循环 |
当l
为空或不存在时,才会输出{% empty %}
下面的内容。
if判断:
{% if xxx %}
……
{% elif yyy %}
……
{% else %}
……
{% endif %}
with起别名:
{% with aba.abb.aab as a %}
{{ a }} 在with语句内,可以直接使用a代表那一大串
{% endwith %}
第一步:
先在app文件夹中,创建一个 templatetags
子文件夹,名称千万不要写错。
第二步:
在 templatetags
文件夹中,创建一个任意名称的.py
文件。
第三步:
在.py
文件中,定义过滤器:
@register.filter(name='your_filter') # 过滤器名字随便写,不写默认使用下面的函数名
def my_filter(): # 函数名随便写
pass
注意:过滤器的参数最多有两个。
第四步:
在模板文件中,使用自定义过滤器:
{% load 自定义过滤器所在py文件的文件名 %}
{{ xxx|过滤器名称:参数 }}
第一步:
先在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文件的文件名 %}
{% 函数名称 参数 …… %}
上面自定义标签的写法只适用于简单的逻辑,更加复杂的逻辑需要更加复杂的写法,建议直接看文档:传送门