模板语法
# 链接资料
django官网
刘江
# 1. 模板常用语法
return render(request,"模板的文件名",{"k1":"xxx"}) #返回一个HTML页面
Django模板中只需要记两种特殊符号:
1.1 和 {% %}
1.2 表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操作。
点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值
数字:{{ num }}
<br>
字符串:{{ string }}
<br>
字典:{{ name_dict }} --> {{ name_dict.keys }} --> {{ name_dict.values }} --> {{ name_dict.name }}
<br>
列表:{{ name_list }} --> {{ name_list.2 }}
<br>
集合:{{ set }} --> {{ set.1 }}
<br>
元组:{{ tup }} --> {{ tup.0 }}
<br>
类:{{ person }} --> {{ person.name }} --> {{ person.talk }}
.
.索引 .key .属性 .方法(方法后面不加括号)
优先级:
.key > .属性 .方法 > .索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2. 过滤器
过滤器的语法:
使用管道符"|"来应用过滤器。
# Filters过滤器
return render(request,"template_text.html",{"new_num":""})
{{变量|过滤器:"参数"}}
default:
变量不存在或者为空时使用默认值 ,如果value值没传的话就显示nothing
{{ new_num|default:"2" }}
1
2
3
4
5
6
2
3
4
5
6
# filesizeformat
# 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)
return render(request, "template_text.html", {"value": 1024 * 1024 * 1024})
{{ value|filesizeformat }} # filesizefomrat:1.0 GB
1
2
3
4
5
2
3
4
5
# add +
给变量加参数
数字的加法,字符串和列表的拼接
add:{{ value2|add:"2" }} --> 列表相加:{{ name_list|add:name_list }} #add:4 --> 列表相加:['张三', '李四', '王五', '张三', '李四', '王五']
1
2
3
2
3
# lower,upper,title
小写:{{value|lower}}
大写:{{value|upper}}
标题:{{value|title}} #首字母大写
可以写在一起:{{value|upper|lower|title}}
1
2
3
4
5
2
3
4
5
# length
{{ value|length }}
返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.
1
2
3
2
3
# slice 切片
{{ name_list|slice:"0:2" }} #和python一样就是没有[]号 [0:2]
1
# first,last
{{value:first}} #取第一个元素 和 {{value.0}}一样
{{value:last}} #取最后一个元素
1
2
2
# join 字符串拼接
使用字符串拼接列表。同python的str.join(list)。
{{ value|join:" __ " }} #张三__李四__王五
1
2
3
2
3
# truncatechars 字符串截取
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:截断的字符数
{{ long_str|truncatechars:9 }} #包括3个省略号 Django...
truncatewords :根据单词截断
1
2
3
4
2
3
4
# date 日期格式化
import datetime
now = datetime.datetime.now()
{{ now|date:"Y-m-d H:i:s" }}2020-08-08 10:17:14
或者直接在settings.py里面定义格式
1. USE_L10N = False
2. 设置格式:
DATETIME_FORMAT = 'Y-m-d H:i:s'
TIME_FORMAT = 'H:i:s'
DATE_FORMAT = ‘Y-m-d
然后直接:{{ now }},就和上面一样的
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全
比如:
"safe_text":"<a href='<https://www.baidu.com>'>点我</a>",
{{ safe_text}}
我们就会在页面上获得字符串:<a href='<https://www.baidu.com>'>点我</a>
有时候我们不想这样,我们就可以加个safe
{{safe_text|safe}} # 点我
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# mark_safe
from django.utils.safestring import mark_safe
@register.filter
def show_b(name,url):
return mark_safe('<a href="{}">{}</a>'.format(url,name)) #直接这样写就不用在用的时候加safe了
{{ '百度'|show_b:"<http://www.baidu.com>" }}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 3. 自定义过滤器 filter
在app下创建一个名为templatetags的python包(包的名字不能错,必须叫templatetags)
创建一个python文件,文件名自定义(mytags.py (opens new window))
创建自定义过滤器:
from django import template register = template.Library() # register的名字不能错 @register.filter def add_arg(value, arg): #只能写二个参数,一个是变量,一个是过滤器的参数 # 功能 return "{}__{}".format(value, arg)
1
2
3
4
5
6
7
8- 在html中使用
在模板中:
{% load mytags %} #先用load加载 mytags这个文件 {{ person.name|add_arg:"我爱你" }}
1
2
# 4. 母版和继承
# 4.1 母版:
1. 一个包含多个页面的公共部分
2. 定义多个block块,让子页面进行覆盖
1
2
3
2
3
# 4.2 继承:
1. {% extends "母版的名字" %} # xx.html
{# 留着模板的内容#}
{{ block.super }}
2. 重新复写block块 (就是覆盖了母版的block块)
1
2
3
4
2
3
4
注意点:
- {% extends "母版的名字" %} 母版的名字带引号
- {% extends "母版的名字" %} 写在第一行,上面不在写内容
- 要显示的内容要写到block块里面
- 多写一个css\js的block块(因为每一个页面的css\js不可能完全一样)
例
创建母版:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>母版</title>
<style>
div{
width: 500px; height: 500px; border: 2px solid red;
}
</style>
{% block css %} {% endblock %} {# css#}
</head>
<body>
<div>
<a href="">你要干什么?</a>
</div>
{% block content %} {# 内容#} {% endblock %}
{% block js %} {# js#} {% endblock %}
</body>
</html>
使用母版:
{% extends "Master.html" %}
{% block css %}
<style>
div{
background-color: blueviolet;
}
</style>
{% endblock %}
{% block content %}
<h1>123321</h1>
{% endblock %}
{% block js %}
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 5. 组件 include
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
1
把一小段公用的HTML文本写入一个HTML文件,nav.html
在需要该组件的模版中导入
{% include 'nav.html' %}
1
示例
创建组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
<style>
*{
list-style: none; margin: 0; padding: 0;
}
div{
height: 50px; border: 1px solid red;
}
div ul li{
width: 100px; height: 35px; border: 1px solid green; margin-left: 50px; float: left;
}
</style>
</head>
<body>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</body>
</html>
使用组件
{% extends "Master.html" %}
{% block css %}
<style>
div{
background-color: blueviolet;
}
</style>
{% endblock %}
{% block content %}
{% include "nav.html" %}
<h1>123321</h1>
{% endblock %}
{% block js %}
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 6. 标签tags
# for
<ul>
{% for name in name_list %}
<li>{{ forloop.counter }}-{{ name }}</li>
{% endfor %}
</ul>
1
2
3
4
5
2
3
4
5
for循环可用的一些参数:
Variable | Description |
---|---|
forloop.counter | 当前循环的索引值(从1开始) |
forloop.counter0 | 当前循环的索引值(从0开始) |
forloop.revcounter | 当前循环的倒序索引值(到1结束) |
forloop.revcounter0 | 当前循环的倒序索引值(到0结束) |
forloop.first | 当前循环是不是第一次循环(布尔值) |
forloop.last | 当前循环是不是最后一次循环(布尔值) |
forloop.parentloop | 本层循环的外层循环 |
# for ...empty
{% for name in name_list2 %}
<li>{{ name }}</li>
{% empty %}
为空了 #如果循环的对象为空的话,就输出它
{% endfor %}
1
2
3
4
5
2
3
4
5
# if
{% if value2 > 2 %}
可以
{% elif value2 == 2 %}
不错
{% endif %}
1
2
3
4
5
2
3
4
5
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
注意:
条件中不支持算术运算
不支持连续判断
{% if 5 > 4 > 1 %} 这样会报错 只有改成{% if 5 > 4 and 4 > 1 %} ok {% else %} no {% endif %}
1
2
3
4
5
# with
就是重命名
{% with name_list as name%}
{{ name }}
{{ name }}
{% endwith %}
或者
{% with name = name_list %}
{{ name }}
{{ name }}
{% endwith %}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 7. 自定义标签 simple_tag
- app应用文文件夹中创建templatetags文件夹,必须是这个名字;
- templatetags文件夹中创建一个xx.py文件,名字可以随便起。
- 创建自定义标签
from django import template
register = template.Library() # register固定的名字
@register.simple_tag
def mytag(v1):
s = v1 + '我爱你'
return s
@register.simple_tag
def mytag2(v1, v2, v3):
s = v1 + v2 + v3
return s
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 使用 html文件中的 {% load 文件名 %} {% load te %}
{% mytag s1 %} {% mytag2 s1 'yyz' 'lt' %} - 注意:参数可以有多个。
# inclusion_tag
filter, simple_tag,inclusion_tag
没有参数限制的
在app下创建一个名为templatetags的python包(包的名字不能错,必须叫templatetags)
创建一个python文件,文件名自定义(mytags.py (opens new window))
在python包中写:
from django import template register = template.Library() # register的名字不能错
1
2
3- 写函数+加装饰器
filter: def add_arg(value,arg): #只能接受一个参数和值 return "xx" simple_tag: @register.simple_tag # 可以接受多个参数和值 def str_join(*args, **kwargs): return "{}_{}".format("---".join(args), "***".join(kwargs)) inclusion_tag: @register.inclusion_tag("page.html") #把值返回到page.html页面上 def pagination(num): return {'num': range(1, num + 1)} # 需要返回的是一个字典
1
2
3
4
5
6
7
8
9
10
11
12
13- 使用
filter: {% load mytags %} {% "alex"| add_arg:"我爱你" %} simple_tag: {% load mytags %} {% str_join "a" "b" "c" k1="aa" k2="bb" %} {#a---b---c_k1***k2#} inclusion_tag: {% load mytags %} {% pagination 6 %}
1
2
3
4
5
6
7
8
9
10
11
12
# 8. 实例(分页)
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
# 方法一
@register.simple_tag
def pagination(num):
page_list = ['<li><a href="#">{}</a></li>'.format(i) for i in range(1,num+1)]
print(page_list)
return mark_safe("""
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>""".format(''.join(page_list)))
# 方法二:
@register.inclusion_tag("page.html")
def pagination(num):
return {'num': range(1, num + 1)} # 需要返回的是一个字典
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% for page in num %}
<li><a href="#">{{ page }}</a></li>
{% endfor %}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
1
编辑 (opens new window)