Django模板语言
-
常用语法
- 变量相关的用
{{ }}
- 逻辑相关的用
{% %}
- 变量相关的用
-
变量
- 在Django的模板语言使用变量的方式为:{{ 变量名 }}。
- 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 变量的命名包括任何字母数字以及下划线的组合。 变量名称中不能有空格或标点符号。
- 点
(.)
在模板语言中有特殊的含义。当模版系统遇到点(.)
,它将以这样的顺序查询:- 字典查询(Dictionary lookup)
- 属性或方法查询(Attribute or method lookup)
- 数字索引查询(Numeric index lookup)
- 注意事项:
- 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
- 如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串) 。
-
Filters(模板过滤器)
- 在Django的模板语言中,通过使用(过滤器)来改变变量的显示。
- 过滤器的语法:
{{ value|filter_name:参数 }}
,使用管道符"|"来应用过滤器,其中value
表示变量名称,filter_name
表示使用的过滤器。 - 注意事项:
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数,例如:
{{ sss|truncatewords:30 }}
,这将显示sss的前30个词。 - 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
- '|'左右没有空格没有空格没有空格。
- Django的模板语言中提供了大约六十个内置过滤器。
-
Filters之default
-
如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
{{ value|default:"默认值"}}
-
-
Filters之length
-
统计返回值的长度,作用于字符串和列表。
{{ value|length }}
-
Filters之filesizeformat
- 将返回值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7 MB。
-
Filters之slice
- 将返回值进行切片
{{ value|slice:"起始索引值:结束索引值" }}
-
Filters之date
- 将返回的时间进行格式化输出
{{ value|date:"Y-m-d H:i:s" }}
-
可用的参数:
| 格式化字符 | 描述 | 示例输出 |
| :--------: | :----------------------------------------------------------: | :----------------------------------------------------------: |
| a |'a.m.'
或'p.m.'
(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间) |'a.m.'
|
| A |'AM'
或'PM'
。 |'AM'
|
| b | 月,文字,3个字母,小写。 |'jan'
|
| B | 未实现。 | |
| c | ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo
) 。 |2008-01-02T10:30:00.000123+02:00
或2008-01-02T10:30:00.000123
如果datetime是天真的 |
| d | 月的日子,带前导零的2位数字。 |'01'
到'31'
|
| D | 一周中的文字,3个字母。 |“星期五”
|
| e | 时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。 |''
、'GMT'
、'-500'
、'US/Eastern'
等 |
| E | 月份,特定地区的替代表示通常用于长日期表示。 |'listopada'
(对于波兰语区域,而不是'Listopad'
) |
| f | 时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。 |'1'
,'1:30'
|
| F | 月,文,长。 |'一月'
|
| g | 小时,12小时格式,无前导零。 |'1'
到'12'
|
| G | 小时,24小时格式,无前导零。 |'0'
到'23'
|
| h | 小时,12小时格式。 |'01'
到'12'
|
| H | 小时,24小时格式。 |'00'
到'23'
|
| i | 分钟。 |'00'
到'59'
|
| I | 夏令时间,无论是否生效。 |'1'
或'0'
|
| j | 没有前导零的月份的日子。 |'1'
到'31'
|
| l | 星期几,文字长。 |'星期五'
|
| L | 布尔值是否是一个闰年。 |True
或False
|
| m | 月,2位数字带前导零。 |'01'
到'12'
|
| M | 月,文字,3个字母。 |“扬”
|
| n | 月无前导零。 |'1'
到'12'
|
| N | 美联社风格的月份缩写。 专有扩展。 |'Jan.'
,'Feb.'
,'March'
,'May'
|
| o | ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。 |'1999年'
|
| O | 与格林威治时间的差异在几小时内。 |'+0200'
|
| P | 时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。 |'1 am'
,'1:30 pm' / t3>,'midnight','noon','12:30 pm' / T10>
|
| r | RFC 5322格式化日期。 |'Thu, 21 Dec 2000 16:01:07 +0200'
|
| s | 秒,带前导零的2位数字。 |'00'
到'59'
|
| S | 一个月的英文序数后缀,2个字符。 |'st'
,'nd'
,'rd'
或'th'
|
| t | 给定月份的天数。 |28
to31
|
| T | 本机的时区。 |'EST'
,'MDT'
|
| u | 微秒。 |000000
to999999
|
| U | 自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。 | |
| w | 星期几,数字无前导零。 |'0'
(星期日)至'6'
(星期六) |
| W | ISO-8601周数,周数从星期一开始。 |1
,53
|
| y | 年份,2位数字。 |'99'
|
| Y | 年,4位数。 |'1999年'
|
| z | 一年中的日子 |0
到365
|
| Z | 时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。 |-43200
到43200
|
-
Filters之safe
- Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。例如:
value = "<a href='#'>点我</a>" {{ value|safe}}
-
Filters之truncatechars
- 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
{{ value|truncatechars:9 }}
-
Filters之truncatewords
- 在一定数量的字后截断字符串。
{{ value|truncatewords:9 }}
-
Filters之cut
- 移除value中所有的与给出的变量相同的字符串
{{ value|cut:' ' }}
如果value为
'i love you'
,那么将输出'iloveyou'
-
Filters之join
- 使用字符串连接列表,例如Python的
str.join(list)
- 使用字符串连接列表,例如Python的
-
Filters之timesince
-
计算自某个日期至某个日期经过了多少时间(例如,“4天,6小时”)。
-
采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:
{{ blog_date|timesince:comment_date }}
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。
-
-
Filters之timeuntil
- 类似于timesince,计算自某个日期至某个日期经过了多少周。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则
{{ conference_date|timeuntil }}
将返回“4周”。
使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:
{{ conference_date|timeuntil:from_date }}
- 类似于timesince,计算自某个日期至某个日期经过了多少周。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则
-
自定义filter
-
第一步:在
app
下新建一个templatetags
包(Python Package),将自定义的代码放入其中。 -
第二步:在
templatetags
中创建自定义的filter,这里我们将自定义的filter命名为myfilter.py
-
第三步:在
myfilter.py
中写自己filter,注意,myfilter.py
中有固定格式:# 从django中导入template(固定写法) from django import template # 生成一个注册器(固定写法) register = template.Library() # 通过装饰器告诉注册器生成了一个叫做myfilter_1的filter @register.filter(name="myfilter_1") def myfilter_1(value, arg): # value表示要修改哪个变量 return value.replace(arg, "") # 通过装饰器告诉注册器生成了一个叫做myfilter_2的filter @register.filter(name="myfilter_2") def myfilter_2(value): return F"{value} mkv"
-
第四步:使用自定义filter(最多只有两个参数)
{# 先导入我们自定义filter那个文件 #} {% load myfilter %} {# 使用我们自定义的filter #} {{ 要修改的变量|myfilter_1:"0" }} {{ 要修改的变量|myfilter_2 }}
-
第五步:重启Django
-
-
Tags(模板标签)
- 模板标签都是放在{% %}括号里的,常见的模板标签有
{% load xxx %}
,{% block xxx %}
,{% if xxx %}
,{% url 'xxxx' %}
。这些模板标签的本质也是函数,标签名一般即为函数名。这些标签的主要作用包括载入代码渲染模板或对传递过来的参数进行一定的逻辑判断或计算后返回。
- 模板标签都是放在{% %}括号里的,常见的模板标签有
-
Tags之for循环
-
普通for循环示例
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% endfor %} </ul>
-
带参数的for循环
Variable Description forloop.counter
获取当前循环的索引值(从1开始) forloop.counter0
获取当前循环的索引值(从0开始) forloop.revcounter
获取当前循环的倒序索引值(从1开始) forloop.revcounter0
获取当前循环的倒序索引值(从0开始) forloop.first
获取当前循环是不是第一次循环(布尔值) forloop.last
获取当前循环是不是最后一次循环(布尔值) forloop.parentloop
获取本层循环的外层循环 -
当循环为空时,单独输出(for ... empty)
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>暂无内容</li> {% endfor %} </ul>
-
-
Tags之if条件判断
-
if…elif…else(可以没有elif)。if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
{% if user_list %} 用户人数:{{ user_list|length }} {% elif black_list %} 黑名单数:{{ black_list|length }} {% else %} 没有用户 {% endif %}
-
-
Tags之with起别名
-
with用于定义一个中间变量,多用于给一个复杂的变量起别名。注意等号左右不要加空格。
{% with total=business.employees.count %} {{ total }} employee {{ total|pluralize }} {% endwith %} # 或者 {% with business.employees.count as total %} {{ total }} employee {{ total|pluralize }} {% endwith %}
-
-
Tags之csrf_token
- 这个标签用于跨站请求伪造保护。在页面的form表单里面写上
{% csrf_token %}
- 这个标签用于跨站请求伪造保护。在页面的form表单里面写上
-
Tags之注释
- 注释使用:
{# ... #}
- 注释使用:
-
注意事项
-
Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %} ... {% endif %}
-
Django的模板语言中属性的优先级大于方法:
def xxx(request): d = {"a": 1, "b": 2, "c": 3, "items": "100"} return render(request, "xxx.html", {"data": d}) # 如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中,{{ data.items }}默认会取d的items key的值。
-
-
母板
-
Django母版页用于处理html页面相同部分内容,避免在不同的页面中重复出现。
-
块(block)
-
通过在母板中使用
{% block xxx %}
来定义"块"。在子页面中通过xxx定义母板中的block名来对应替换母板中相应的内容。{% block page-main %} <p>这是在子页面中的块内容,用于替换模板中占位的块</p> {% endblock %}
-
-
组件
-
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
{% include 'navbar.html' %}
-
-
-
母版的创建
-
在
manage.py
文件相同目录下的templates文件夹中保存母版页html文件 -
添加母版页
Base.html
,html文件内容如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> {# 母板中定义专用的CSS块,方便子页面进行替换 #} {% block page-css %} {% endblock %} </head> <body> <h1>这是母板的标题</h1> {# 使用 block进行占位,page-mian是给block起的一个名字,子页面中通过这个名字找到要替换内容的位置 #} {% block page-main %} {% endblock %} <h1>母板底部内容</h1> {# 母板中定义专用的JS块,方便子页面进行替换 #} {% block page-js %} {% endblock %} </body> </html>
注意:我们通常会在母板中定义专用的CSS块和JS块,方便子页面替换。
-
由于母版页和子页面不在同一个app下,需要在主模块的
settings.py
文件里面进行路径配置,在同一app下则不需要配置,在TEMPLATES 下的DIRS里面配置母版页所在路径。
-
- 母板的继承
-
在子页面中在页面最上方使用下面的语法来继承母板
{# 继承模板 #} {% extends 'Base.html' %} {# 将子页面的内容写到block中 #} {% block page-main %} <p>子页面中与母版不同的内容<p> {% endblock %}
注意:
view.py
中的函数返回的是对应的子页面,而不是base.html
。
-
静态文件相关
为了规避
setting.py
中STATIC_URL = '/static/'
的/static/
被修改成其他名称,会造成所有引入静态文件失效的问题,Django的模板语言可以通过如下方式对静态文件加载。-
方式一(自动拼接,首选这种方式):
{% static %}
{% load static %} <img src="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet" /> {# 某个文件多处被用到可以存为一个变量 #} {% load static %} {% static "images/photo.jpg" as myphoto %} <img src="{{ myphoto }}"></img>
-
方式二(手动拼接):
{% get_static_prefix %}
{% load static %} <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
-
-
simple_tag
-
和自定义filter类似,只不过simple_tag可以更灵活的接受参数。
-
第一步:在
app
下新建一个templatetags
包(Python Package),将自定义simple_tag文件放入其中。 -
第二步:在
templatetags
包中创建自定的simple_tag文件,这里创建一个名为my_simple_tag.py
的文件。 -
第三步:编辑
my_simple_tag.py
(有固定格式)。# 从django中导入template(固定写法) from django import template # 生成一个注册器(固定写法) register = template.Library() # 通过装饰器告诉注册器生成了一个叫做my_simple_tag的simple_tag @register.simple_tag(name="my_simple_tag") def my_simple_tag(arg1, arg2, arg3): return F"{arg1}+{arg2}+{arg3}"
-
第四步:在HTML文件中使用自定义的simple_tag。
{% load my_simple_tag %} {% my_simple_tag "你好" "我好" "大家好" %}
-
第五步:重启Django后查看自定义simple_tag是否生效。
-
-
inclusion_tag
-
多用于返回HTML代码片段。
-
第一步:在
app
下新建一个templatetags
包(Python Package),将自定义inclusion_tag文件放入其中。 -
第二步:在
templatetags
包中创建自定的inclusion_tag文件,这里创建一个名为my_inclusion_tag.py
的文件。 -
第三步:编辑
my_inclusion_tag.py
(有固定格式)。# 从django中导入template(固定写法) from django import template # 生成一个注册器(固定写法) register = template.Library() # 通过装饰器告诉注册器生成了一个叫做my_inclusion_tag.html的inclusion_tag @register.inclusion_tag('my_inclusion_tag.html') def my_inclusion_tag(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data}
-
第四步:在Django项目的templates文件夹中,创建一个
my_inclusion_tag.html
<ul> {% for choice in data %} <li>{{ choice }}</li> {% endfor %} </ul>
-
第五步:在HTML文件中,使用inclusion_tag。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>inclusion_tag test</title> </head> <body> {% load inclusion_tag_test %} {% show_results 10 %} </body> </html>
-
网友评论