模板
1、模板語法之變量
- {{ comment.create_time|date:"Y-m-d H:i:s" }}
- {{ bio|truncatewords:"30" }}
- {{ my_list|first|upper }}
- {{ name|lower }}
- {{ forloop.counter }}
- {{ forloop.first }}
- {{ forloop.last }}
在 Django 模板中遍歷複雜數據結構的關鍵是句點字符, 語法: {{var_name}}css
1
2
3
4
5
6
|
<h4>{{s}}<
/
h4>
<h4>列表:{{ l.
0
}}<
/
h4>
<h4>列表:{{ l.
2
}}<
/
h4>
<h4>字典:{{ dic.name }}<
/
h4>
<h4>日期:{{ date.year }}<
/
h4>
<h4>類對象列表:{{ person_list.
0.name
}}<
/
h4>
|
2、模板之過濾器
語法:{{obj|filter__name:param}}html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
default:若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如:
{{ value|default:
"nothing"
}}
length:返回值的長度。它對字符串和列表都起做用。例如:
{{ value|length }} 若是 value 是 [
'a'
,
'b'
,
'c'
,
'd'
],那麼輸出是
4
。
filesizeformat:將值格式化爲一個 「人類可讀的」 文件尺寸 (例如
'13 KB'
,
'4.1 MB'
,
'102 bytes'
, 等等)。例如:
{{ value|filesizeformat }} 若是 value 是
123456789
,輸出將會是
117.7
MB。
date:若是 value
=
datetime.datetime.now()
{{ value|date:
"Y-m-d"
}}
slice
:若是 value
=
"hello world"
{{ value|
slice
:
"2:-1"
}}
truncatechars:
若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。
參數:要截斷的字符數
{{ value|truncatechars:
9
}}
safe:Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,這樣是爲了安全。若是不但願HTML元素被轉義,能夠這樣:
value
=
"<a href="
">點擊</a>"
{{ value|safe}}
|
這裏簡單介紹一些經常使用的模板的過濾器,更多詳見python
3、模板之標籤
標籤看起來像是這樣的: {% tag %}。標籤比變量更加複雜:一些在輸出中建立文本,一些經過循環或邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模版中。一些標籤須要開始和結束標籤 (例如{% tag %} ...標籤 內容 ... {% endtag %})。git
一、for標籤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
"""
遍歷每個元素:
{% for person in person_list %}
<p>{{ person.name }}</p>
{% endfor %}
能夠利用{% for obj in list reversed %}反向完成循環。
遍歷一個字典:
{% for key,val in dic.items %}
<p>{{ forloop.counter }} {{ key }}:{{ val }}</p>
{% endfor %}
注:循環序號能夠經過{{ forloop }}顯示
forloop.counter The current iteration of the loop (1-indexed)
forloop.counter0 The current iteration of the loop (0-indexed)
forloop.revcounter The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed)
forloop.first True if this is the first time through the loop
forloop.last True if this is the last time through the loop
"""
|
二、for ... empty
1
2
3
4
5
6
|
<!
-
-
for
標籤帶有一個可選的{
%
empty
%
} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。
-
-
>
{
%
for
person
in
person_list
%
}
<p>{{ forloop.counter0 }} {{ person.name }} , {{ person.age }}<
/
p>
{
%
empty
%
}
<p>列表爲空<
/
p>
{
%
endfor
%
}
|
三、if 標籤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!
-
-
注意:
filter
能夠用在
if
等語句後,simple_tag不能夠
-
-
>
{
%
if
i|multi_fliter:
10
>
100
%
}
<p>
100
<
/
p>
{
%
else
%
}
<p>{{ i }}<
/
p>
{
%
endif
%
}
<!
-
-
多分支
-
-
>
{
%
if
num >
100
or
num <
0
%
}
<p>無效<
/
p>
{
%
elif
num >
80
and
num <
100
%
}
<p>優秀<
/
p>
{
%
else
%
}
<p>湊活吧<
/
p>
{
%
endif
%
}
|
四、with
1
2
3
4
5
|
<!
-
-
使用一個簡單地名字緩存一個複雜的變量
-
-
>
{
%
with person_list.
1.name
as n
%
}
{{ n }}
{{ n }}
{
%
endwith
%
}
|
五、csrf_token
1
2
3
4
5
|
<form action
=
"
" method="
post">
{
%
csrf_token
%
} <!
-
-
這個標籤用於跨站請求僞造保護
-
-
>
<
input
type
=
"text"
name
=
"user"
>
<
input
type
=
"submit"
>
<
/
form>
|
4、自定義標籤和過濾器
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
|
"""
一、在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag.
二、在app中建立templatetags包(包名只能是templatetags)
三、建立任意 .py 文件,如:my_tags.py
四、在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tags.py
五、使用simple_tag和filter(如何調用)
注意:filter能夠用在if等語句後,simple_tag不能夠
"""
#settings.py
INSTALLED_APPS
=
[
'django.contrib.admin'
,
'django.contrib.auth'
,
'django.contrib.contenttypes'
,
'django.contrib.sessions'
,
'django.contrib.messages'
,
'django.contrib.staticfiles'
,
"app01"
,
#配置當前app
]
# app01.templatetags.my_tags.py
from
django
import
template
from
django.utils.safestring
import
mark_safe
register
=
template.Library()
# register的名字是固定的,不可改變
@register
.
filter
#自定義過濾器最多2個參數
def
multi_fliter(v1, v2):
return
v1
*
v2
@register
.simple_tag
#自定義標籤,沒有參數個數限制
def
multi_tag(v1, v2, v3):
return
v1
*
v2
*
v3
@register
.simple_tag
def
my_input(
id
, arg):
result
=
"<input type='text' id='%s' class='%s' />"
%
(
id
, arg,)
return
mark_safe(result)
#模板中:
"""
{% load my_tags %} <!--注意:這塊更改過要重啓項目-->
# num = 8
<p>{{ num|multi_fliter:20 }}</p>
<p>{% multi_tag 7 9 6 %}</p>
<!--注意:filter能夠用在if等語句後,simple_tag不能夠-->
{% if num|multi_fliter:10 > 100 %}
<p>100</p>
{% else %}
<p>{{ num }}</p>
{% endif %}
"""
|
5、模板之inclusion_tag
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
|
# app01.templatetags.my_tags.py
from
django
import
template
from
django.db.models
import
Count
from
app01
import
models
register
=
template.Library()
@register
.simple_tag
def
multi_tag(x,y):
return
x
*
y
@register
.inclusion_tag(
"classification.html"
)
def
get_classification_style(username):
user
=
models.UserInfo.objects.
filter
(username
=
username).first()
blog
=
user.blog
cate_list
=
models.Category.objects.
filter
(blog
=
blog).values(
"pk"
).annotate(c
=
Count(
"article__title"
)).values_list(
"title"
,
"c"
)
tag_list
=
models.Tag.objects.
filter
(blog
=
blog).values(
"pk"
).annotate(c
=
Count(
"article"
)).values_list(
"title"
,
"c"
)
date_list
=
models.Article.objects.
filter
(user
=
user).extra(select
=
{
"y_m_date"
:
"date_format(create_time,'%%Y/%%m')"
}).values(
"y_m_date"
).annotate(c
=
Count(
"nid"
)).values_list(
"y_m_date"
,
"c"
)
return
{
"blog"
:blog,
"cate_list"
:cate_list,
"date_list"
:date_list,
"tag_list"
:tag_list}
#模板中:使用
"""
<div class="col-md-3 menu">
{% load my_tags %}
{% get_classification_style username %}
</div>
"""
#templates.classification.html
"""
<div>
<div class="panel panel-warning">
<div class="panel-heading">個人標籤</div>
<div class="panel-body">
{% for tag in tag_list %}
<p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">隨筆分類</div>
<div class="panel-body">
{% for cate in cate_list %}
<p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">隨筆歸檔</div>
<div class="panel-body">
{% for date in date_list %}
<p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
{% endfor %}
</div>
</div>
</div>
"""
|
6、模板繼承 (extend)
- 不能在一個模版中定義多個相同名字的 block 標籤。
- 爲了更好的可讀性,你也能夠給你的 {% endblock %} 標籤一個 名字 。例如:{% block content %}...{% endblock content %}
- 子模版沒必要定義所有父模版中的blocks
- {% extends 'base.html' %}
一、製做模板
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
|
<!
-
-
模版 base.html
-
-
>
<!DOCTYPE html>
<html lang
=
"en"
>
<head>
<meta charset
=
"UTF-8"
>
{
%
block title
%
}
<title>base<
/
title>
{
%
endblock
%
}
{
%
block css
%
} {
%
endblock
%
}
<
/
head>
<body>
<div
class
=
"header"
><
/
div>
<div
class
=
"container"
>
<div
class
=
"row"
>
<div
class
=
"col-md-3"
>
{
%
include
'left1.html'
%
} <!
-
-
引入小組件
-
-
>
{
%
include
'ad.html'
%
} <!
-
-
引入小組件
-
-
>
<
/
div>
<div
class
=
"col-md-9"
>
{
%
block con
%
}
<h4>content<
/
h4>
{
%
endblock content
%
} <!
-
-
更好的可讀性
-
-
>
<
/
div>
<
/
div>
<
/
div>
{
%
block js
%
}{
%
endblock
%
}
<
/
body>
<
/
html>
|
二、繼承模板
1
2
3
4
5
6
7
8
9
10
11
12
|
{
%
extends
'base.html'
%
} <!
-
-
它必須是模版中的第一個標籤。
-
-
>
{
%
block title
%
}
<title>orders<
/
title>
{
%
endblock
%
}
{
%
block con
%
}
{{ block.
super
}} <!
-
-
獲取模板中con的內容
-
-
>
<h4>訂單<
/
h4>
{
%
endblock con
%
}
<!
-
-
order.html
-
-
>
|
7、模板多對多調用
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
|
class
Student(models.Model):
name
=
models.CharField(max_length
=
128
)
class
Course(models.Model):
name
=
models.CharField(max_length
=
128
)
students
=
models.ManyToManyField(
'Student'
)
正向查詢:
從course往student查
def
test(request):
course
=
models.Course.objects.get(pk
=
1
)
return
render(request,
'course.html'
,
locals
())
獲取了
id
爲
1
的course對象,並將它傳遞給course.html模版,模版代碼以下:
{
%
for
student
in
course.students.
all
%
}
<p>{{ student.name }}<
/
p>
{
%
endfor
%
}
首先經過course.students.
all
,查尋到course對象關聯的students對象集,而後用
for
標籤循環它,獲取每一個student對象,再用student模型的定義,訪問其各個字段的屬性。
反向查詢:
從student往course查,假設有以下的視圖:
def
test2(request):
student
=
models.Student.objects.get(pk
=
1
)
return
render(request,
'student.html'
,
locals
())
獲取了
id
爲
1
的student對象,並將它傳遞給student.html模版,模版代碼以下:
{
%
for
course
in
student.course_set.
all
%
}
{{ course.name }}
{
%
endfor
%
}
經過student.course_set.
all
,反向獲取到student實例對應的全部course對象,而後再
for
標籤循環每一個course,調用course的各類字段屬性。
####
對於外鍵ForeignKey,其用法基本相似。只不過正向是obj.fk,且只有
1
個對像,不是集合。反向則是obj.fk_set,相似多對多。
|
8、內置模板標籤
標籤 | 說明 |
---|---|
autoescape | 自動轉義開關 |
block | 塊引用 |
comment | 註釋 |
csrf_token | CSRF令牌 |
cycle | 循環對象的值 |
debug | 調試模式 |
extends | 繼承模版 |
filter | 過濾功能 |
firstof | 輸出第一個不爲False的參數 |
for | 循環對象 |
for … empty | 帶empty說明的循環 |
if | 條件判斷 |
ifequal | 若是等於 |
ifnotequal | 若是不等於 |
ifchanged | 若是有變化,則.. |
include | 導入子模版的內容 |
load | 加載標籤和過濾器 |
lorem | 生成無用的廢話 |
now | 當前時間 |
regroup | 根據對象重組集合 |
resetcycle | 重置循環 |
spaceless | 去除空白 |
templatetag | 轉義模版標籤符號 |
url | 獲取url字符串 |
verbatim | 禁用模版引擎 |
widthratio | 寬度比例 |
with | 上下文變量管理器 |
9、內置過濾器總覽
爲模版過濾器提供參數的方式是:過濾器後加個冒號,再緊跟參數,中間不能有空格! 目前只能爲過濾器最多提供一個參數!django
過濾器 | 說明 |
---|---|
add | 加法 |
addslashes | 添加斜槓 |
capfirst | 首字母大寫 |
center | 文本居中 |
cut | 切除字符 |
date | 日期格式化 |
default | 設置默認值 |
default_if_none | 爲None設置默認值 |
dictsort | 字典排序 |
dictsortreversed | 字典反向排序 |
divisibleby | 整除判斷 |
escape | 轉義 |
escapejs | 轉義js代碼 |
filesizeformat | 文件尺寸人性化顯示 |
first | 第一個元素 |
floatformat | 浮點數格式化 |
force_escape | 強制馬上轉義 |
get_digit | 獲取數字 |
iriencode | 轉換IRI |
join | 字符列表連接 |
last | 最後一個 |
length | 長度 |
length_is | 長度等於 |
linebreaks | 行轉換 |
linebreaksbr | 行轉換 |
linenumbers | 行號 |
ljust | 左對齊 |
lower | 小寫 |
make_list | 分割成字符列表 |
phone2numeric | 電話號碼 |
pluralize | 複數形式 |
pprint | 調試 |
random | 隨機獲取 |
rjust | 右對齊 |
safe | 安全確認 |
safeseq | 列表安全確認 |
slice | 切片 |
slugify | 轉換成ASCII |
stringformat | 字符串格式化 |
striptags | 去除HTML中的標籤 |
time | 時間格式化 |
timesince | 從什麼時候開始 |
timeuntil | 到什麼時候多久 |
title | 全部單詞首字母大寫 |
truncatechars | 截斷字符 |
truncatechars_html | 截斷字符 |
truncatewords | 截斷單詞 |
truncatewords_html | 截斷單詞 |
unordered_list | 無序列表 |
upper | 大寫 |
urlencode | 轉義url |
urlize | url轉成可點擊的連接 |
urlizetrunc | urlize的截斷方式 |
wordcount | 單詞計數 |
wordwrap | 單詞包裹 |
yesno | 將True,False和None,映射成字符串‘yes’,‘no’,‘maybe’ |