python框架-Django框架Template

摘要

Django框架中Template知识点

  • Template

组成:HTML代码+逻辑控制代码

模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签)文件,然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

变量

深度变量的查找:万能的句点号

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
50
{{ item }}

# 基本使用

## 用于访问列表索引
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'

## 访问字典的值
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'

## 访问时间对象的属性
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
>>> d.month
>>> d.day
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
'The month is 5 and the year is 1993.'

## 访问类的属性
>>> from django.template import Template, Context
>>> class Person(object):
... def __init__(self, first_name, last_name):
... self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'

## 访问对象的属性
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'

# 注意这里调用方法时并没有使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的方法。

变量的过滤器

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
{{obj|filter:param}}

# addvalue的值增加2
{{ value | add: "2"}}

# addslashesvalue中的引号前增加反斜线
{{ value | addslashes }}

# capfirst value的第一个字符转化成大写形式
{{ value | capfirst }}

# cut 从给定value中删除所有arg的值
{{ value | cut:arg }}
## 如果value是“String with spacesarg是" "那么输出是"Stringwithspaces"

# date 将日期格式数据按照给定的格式输出
{{ value | date:"D d M Y" }}
## 如果value是一个datetime对象(datetime.datetime.now())那么输出将是字符串"Wed 09 Jan 2008"
{{ value | date }}
## 这种形式没有格式化字符串,这时候,格式化字符串会自动采用DATE_FORMAT所设置的形式。

# default 如果value的意义是False,那么输出使用缺省值
{{ value | default: "nothing" }}
## 如果value是“”,那么输出将是nothing

# default_if_none 如果valueNone,那么输出将使用缺省值
{{ value | default_if_none:"nothing" }}
## 如果valueNone,那么输出将是nothing

# dictsort 如果value的值是一个字典,那么返回值是按照关键字排序的结果
{{ value | dictsort:"name" }}

# dictsortreversed 如果value的值是一个字典,那么返回值是按照关键字排序的结果的反序
{{ value | dictsortreversed:"name" }}

# divisibleby 如果value能够被arg整除,那么返回值将是True
{{ value | divisibleby:arg }}
## 如果value是21,arg是3,那么输出将是True

# first 返回列表中的第一个Item
{{ value | first }}
## 如果value是列表['a','b','c'],那么输出将是'a'。

# last 返回列表中的最后一个Item
{{ value | last }}

# length 返回value的长度
{{ value | length }}

# length_is 如果value的长度等于arg的时候,返回True
{{ value | length_is:"arg" }}
## 如果value['a','b','c']arg是3,那么返回True

# title 转换一个字符串成为title格式。
{{ value | title }}

# upper 转换一个字符串为大写形式
{{ value | upper }}

# lower 将一个字符串转换成小写形式
{{ value | title }}

# wordcount 返回字符串中单词的数目
{{ value | wordcount }}

# wordwrap 按照指定的长度包装字符串
{{ value | wordwrap:5 }}
## 如果valueJoel is a slug,那么输出将会是: Joel is a slug

# linenumbers 显示的文本,带有行数。
{{ value | linenumbers }}

# ljust 在一个给定宽度的字段中,左对齐显示value
{{ value | ljust }}

# center 在一个给定宽度的字段中,中心对齐显示value
{{ value | center }}

# rjust 在一个给定宽度的字段中,右对齐显示value
{{ value | rjust }}

# join 使用指定的字符串连接一个list,作用如同pythonstr.join(list)
{{ value | join:"arg" }}
## 如果value是['a','b','c'],arg是'//'那么输出是a//b//c

# make_listvalue转换成一个list
{{ value | make_list }}
## 对于字符串,转换成字符list
## 对于整数,转换成整数list

# random 从给定的list中返回一个任意的Item
{{ value | random }}

# slicepython语法中的slice相同,:2表示第一的第二个元素
{{ some_list | slice:"2:-1" }}

# floatformat
{{ value | floatformat }}
{{ value|floatformat:arg }}
## arg可以是正数也可以是负数
## 没有参数的floatformat相当于floatformat:-1
### 如果不带arg,那么引擎会四舍五入,同时最多只保留一位小数。
34.23234 {{ value|floatformat }} 34.2
34.00000 {{ value|floatformat }} 34
34.26000 {{ value|floatformat }} 34.3

### 如果arg是正数,那么引擎会四舍五入,同时保留arg位的小数。
34.23234 {{ value|floatformat:3 }} 34.232
34.00000 {{ value|floatformat:3 }} 34.000
34.26000 {{ value|floatformat:3 }} 34.260

### 如果arg是负数,那么引擎会四舍五入,如果有小数部分,那么保留arg位小数;否则,则没有任何小数部分。
34.23234 {{ value|floatformat:"-3" }} 34.232
34.00000 {{ value|floatformat:"-3" }} 34
34.26000 {{ value|floatformat:"-3" }} 34.26

# get_digit 给定一个数字,返回,请求的数字
{{ value | get_digit:"arg" }}
## 如果value是123456789,arg是2,那么输出是8
## 1代表最右边的数字,如果value不是合法输入, 那么会返回所有原有值。

# escape 替换value中的某些字符,以适应HTML格式
{{ value | escape}}
## 包括: < is converted to &lt; > is converted to &gt; ’ (single quote) is converted to &#39; ” (double quote) is converted to &quot; & is converted to &amp;
## escape仅仅在输出的时候才起作用,所以escape不能够用在链式过滤器的中间
## 他应该总是最后一个过滤器,如果想在链式过滤器的中间使用,那么可以使用force_escape

# escapejs 替换value中的某些字符,以适应JAVASCRIPTJSON格式
{{ value | escapejs }}

# filesizeformat 格式化value,使其成为易读的文件大小
{{ value | filesizeformat }}
## 例如:13KB,4.1MB

# iriencode
{{value | iriencode }}
## 如果value中有非ASCII字符,那么将其进行抓化成URL中适合的编码,如果value已经进行过URLENCODE, 改操作就不会再起作用

# urlencode 将一个字符串进行URLEncode
{{ value | urlencode }}

# linebreaks
{{ value|linebreaks }}
## value中的"\n"将被<br/>替代,并且整个value使用</p>包围起来,从而适和HTML的格式

# linebreaksbr value中的"\n"将被<br/>替代
{{ value |linebreaksbr }}

# safe 系统设置autoescaping打开的时候,该过滤器使得输出不进行escape转换
{{ value | safe }}

# autoescape 类似safe,范围内都不转换
{% autoescape off %}
{{ value }}
{% endautoescape %}


# safeseq
## 与上述safe基本相同,但有一点不同的就是:safe是针对字符串,而safeseq是针对多个字符串组成的sequence

# pluralize 如果value不是1,则返回一个复数后缀,缺省的后缀是's'
{{ value | pluralize }}
{{ value | pluralize:"es" }}
{{ value | pluralize:"y,ies" }}

# removetags 删除valuetag1,tag2….的标签
{{ value | removetags:"tag1 tag2 tag3…" }}
## 如果value是<b>Joel</b> <button>is</button> a <span>slug</span>
## tags是"b span",那么输出将是:Joel <button>is</button> a slug

# striptags 删除value中的所有HTML标签
{{ value | striptags }}

# slugifyvalue转换成小写形式,同时删除所有分单词字符,并将空格变成横线
{{ value | slugify }}
## 如果valueJoel is a slug,那么输出将是joel-is-a-slug

# stringformat
{{ value|stringformat:"E" }}
## If value is 10, the output will be 1.000000E+01

# time 格式化时间输出,如果time后面没有格式化参数,那么输出按照TIME_FORMAT中设置的进行
{{ value | time:"H:i" }}
{{ value | time }}

# truncatewordsvalue切成truncatewords指定的单词数目
{{ value | truncatewords:2 }}
## 如果valueJoel is a slug 那么输出将是:Joel is

# truncatewords_html
{{ value | truncatewords_html:2 }}
## 之前如果某个标签打开了,但是没有关闭,那么会立即关闭
## 因为这个操作的效率比truncatewords低,所有只有在valuehtml格式时,才考虑使用。

# urlize 将一个字符串中的URL转化成可点击的形式a标签
{{ value | urlize }}

# urlizetruncurlize类似,
{{ value | urlizetrunc:15 }}

# timesince 返回参数argvalue的天数和小时数
{{ comment_date|timesince:blog_date }}
## 例如,如果 blog_date 是一个日期实例表示 2006-06-01 午夜,而 comment_date 是一个日期实例表示 2006-06-01 早上8点,那么将返回 “8 hours”.

# timeuntiltimesince类似,返回的是value距离当前日期的天数和小时数
{{ value | timeuntil }}

标签

for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% for item in item_list %}
## 反向迭代
{% for item in item_list reversed %}

<a>{{ item }}</a>
## item是空的或者没有被找到时,可以有所操作
{% empty %}
<p>sorry,no person here</p>
{% endfor %}
## 不支持中断循环,也不支持continue语句

# 循环字典
{% for k,v in d.items %}
<p>{{ k }},{{ v}}</p>
{% endfor %}

forloop方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## forloop.counter 表示循环的次数,它从1开始计数
## forloop.counter0 从0开始计数
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

## forloop.revcounter 反向计数 forloop.revcounter0 从0开始计数

## forloop.first 当第一次循环时值为True
{% for object in objects %}
{% if forloop.first %}
<li class="first">
{% else %}
<li>
{% endif %}
{{ object }}</li>
{% endfor %}

## forloop.last 最后一次循环时执行
  • forloop变量只能在循环中得到,当模板解析器到达endforforloop就消失了
  • 如果你的模板context已经包含一个叫forloop的变量,Django会用for标签中覆盖你定义的forloop变量的值
  • 在其他非循环的地方,你的forloop变量仍然可用

if语句

1
2
3
4
5
6
7
{% if ordered_warranty %}
...
{% elif %}
...
{% else %}
...
{% endif %}

包含 include

  • 该标签允许在(模板中)包含其它的模板的内容。
  • 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串
  • 每当在多个模板中出现相同的代码时,就应该考虑是否要使用include来减少重复
1
{% include "tag.html" %}

模板的继承

  • extends必须是子板的第一个模板标记
  • 一般来说,基础模板中的block标签越多越好
    • 子模板不必定义父模板中所有的代码块
    • 可以用合理的缺省值对一些代码块进行填充
  • 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个block中
  • 不允许在同一个模板中定义多个同名的block
1
2
3
4
5
6
7
8
# 母板:
{% block title %}{% endblock %}

# 子板:
{% extends "base.html" %}
{% block title %}{% endblock %}
## 显示母板block中的内容
{{ block.super }}

其他

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
# 跨站请求伪造保护
{% csrf_token %}
## 用于生成csrf_token的标签,用于防治跨站攻击验证。注意如果你在viewindex里用的是render_to_response方法,不会生效
## 这里是会生成一个input标签,和其他表单标签一起提交给后台的。

# 引用路由配置的地址别名
{% url %}

# with:使用一个简单地名字缓存一个复杂的变量
{% with total=business.employees.count %}
{{ total }} employee {{ total|pluralize }}
{% endwith %}

<p>{{ person_list.2.name }}</p>
{% with name=person_list.2.name %}
<p>{{ name }}</p>
{% endwith %}

# 禁止render
{% verbatim %}
{{ hello }}
# 页面直接显示{{ hello }}
{% endverbatim %}

# 加载标签库
## 加载静态文件
{% load staticfiles %}
## 加载自定义的filter
{% load xxx %}

自定义simple_tag标签和过滤

  • 在app中创建templatetags模块,名字不能改
  • 创建任意py文件
  • 创建register = template.Library()对象,名字不能改
  • 自定义标签无参数个数限制,不能进行逻辑判断
  • 自定义过滤器函数的参数只能两个,不能加空格,可以进行逻辑判断
  • 使用
    • 注册app
    • load py文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# xx.py
from django import template
from django.utils.safestring import mark_safe

# register的名字是固定的,不可改变
register = template.Library()

# 自定义tag
@register.simple_tag
def my_simple_time(v1,v2,v3):
return v1 + v2 + v3

# 自定义tag
@register.simple_tag
def my_input(id,arg):
result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
return mark_safe(result)

# 自定义filter
@register.filter
def multi(x,y):
return x*y

在模板中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 在使用自定义simple_taghtml文件中导入之前创建的 xx.py 文件名
{% load xx %}

# 使用simple_tag
## 不能放在if for语句中
{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

## 过滤的用法
{{ num|multi:2 }}
## 相当于复制了,把[22,333,4444]乘了num
{{ num|multi:"[22,333,4444]" }}

## if判断
{% if i|multi:5 > 1000 %}
<p>大于{{ i }}</p>
{% else %}
<p>大于等于{{ i }}</p>
{% endif %}