第5章深入模板
參考:https://www.cnblogs.com/zhaop8078/p/11537807.html
第五章 模板
Django可以配置一個或多個模板引擎(甚至是0,如果不需要使用模板),模板系統有Django模板語言(Django Template Language)和Jinja2。Django模板語言是Django內建的模板語言,Jinja2是當前Python最流行的模板語言。
5.1變數與標籤
變數以{{ variable }}表示,variable是變數名,變數的型別可以是Python支援的資料型別,使用如下:
# variable為字串型別或整型,如variable = "Python"{{ variable }} # 輸出Python # variable為字典或資料物件,通過點號(.)來訪問其屬性值 variable = {"name": "Lily", "info": {"home": "BeiJing", "homeplace": "ShangHai"}} {{ variable.name }} {{ variable.info.home }}
1.以MyDjango為例,抽取模板index.html的部分程式碼,程式碼如下:
<head> <title>{{ title }}</title> <meta charset="utf-8"> {% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static "css/hw_index.css" %}" > <link rel="icon" href="{% static "img/hw.ico" %}"> <script src="{% static "js/hw_index.js" %}"></script> </head> <ul id="cate_box" class="lf"> {% for type in type_list %}<li> <h3><a href="#">{{ type.type }}</a></h3> <p> {% for name in name_list %} {% if name.type == type.type %} <span>{{ name.name }}</span> {% endif %} {% endfor %} </p> </li> {% endfor %} </ul>
上述程式碼分別使用模板的變數和標籤,程式碼說明如下:
1、{{ title }} 代表模板變數,從變數名title可以,變數的資料型別是字串型別或整型。
2、{% load staticfiles %} load標籤用於匯入靜態資源資訊。
3、{% static "css/hw_index.css" %} static標籤用於讀取靜態資源的檔案內容。
4、{% for type in type_list %} 是for便利標籤,將變數進行遍歷輸出。
5、{% if name.type == type.type %} 是if判斷標籤,主要對變數進行判斷處理。
6、{{ type.type }} 代表變數type_list的某個屬性。
從上面的例子可以看到,模板的變數需要和標籤相互結合使用。補充:
# if標籤 {% if name == "Lily" %} {{ name }} {% elif name == "Lucy" %} {{ name }} {% else %} {{ name }} {% endif %} # 帶變數和不帶變數的URL地址 # path('', views.index, name='index') # path('search/<int:page>.html', views.search, name='search') # 字串index是URL的引數name的值,1是URL的變數page的值 <a href="{% url 'index' %}" target="_blank">首頁</a> <a href="{% url 'search' 1 %}" target="_blank">第一頁</a> # 給變數重新命名 {% with total = products_total %} {{ total }} {% endwith %}
2.在for標籤中,模板還提供一些特殊的變數來獲取for標籤的迴圈資訊,變數說明如下:
{% for name in name_list %} {% if forloop.counter == 1 %} <span>這是第一次迴圈</span> {% elif forloop.last %} <span>這是最後一次迴圈</span> {% else %} <span>本次迴圈次數為: {{ forloop.counter }}</span> {% endif %} {% endfor %}
forloop.counter 獲取當前迴圈的索引,從1開始計算
forloop.counter() 獲取當前迴圈的索引,從0開始計算
forloop.revcounter 索引從最大數開始遞減,直到索引到1位置
forloop.revcounter() 索引從最大數開始遞減,直到索引到0位置
forloop.first 當遍歷的元素為第一項時為真
forloop.last 當遍歷的元素為最後一項時為真
forloop.parentloop 在巢狀的for迴圈中,獲取上層for迴圈的forloop
5.2 模板繼承
模板繼承有兩種方式,一種是在母版中定義內容{% block body %} XXXXX {% endblock %},其它頁面繼承;另一種如下例,母版中定義空的內容塊,繼承的頁面來重寫;
base.html。共用模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ title }}</title> </head> <body> {% block body %}{% endblock %} </body> </html>
index.html。呼叫共用模板base.html:
{% extends "base.html" %} {% block body %} <a href="{% url 'index' %}" target="_blank">首頁</a> <he>Hello Django</he> {% endblock %}
5.3 自定義過濾器
5.3.1 內建過濾器如下:中間的” | “是管道符。
內建過濾器 | 使用形式 | 說明 |
add | {{ value | add: "2" }} | 將value的值增加2 |
addslashes | {{ value | addslashes }} | 在value中的引號前增加反斜線 |
capfirst | {{ value | capfirst }} | value的第一個字元轉化成大寫形式 |
cut | {{ value | cut:arg }} | 從value中刪除所有arg的值。如果value是"String with spaces", arg是" ",那麼輸出的是"Stringwithspaces" |
date | {{ value | date:"D d M Y" }} | 將日期格式資料按照給定的格式輸出 |
default | {{ value | default:"nothing" }} | 如果value的意義是False,那麼輸出值為過濾器設定的預設值 |
default_if_none | {{ value | default_if_none:"nothing }} | 如果value的意義是None,那麼輸出值為過濾器設定的預設值 |
dictsort | {{ value | dictsort:"name" }} | 如果value的值是一個列表,裡面的元素是字典,那麼返回值按照每個字典的關鍵字排序 |
dictsortreversed | {{ value | dictsortreversed:arg }} | 如果value的值是一個列表,裡面的元素是字典,每個字典的關鍵字反序排行 |
divisibleby | {{ value |divisibleby:arg }} | 如果value能夠被arg整除,那麼返回值將是True |
escape | {{ value |escape}} | 控制HTML轉義,替換value中的某些HTML特殊字元 |
escapejs | {{ value |escapejs}} | 替換value中的某些字元,以適應JavaScript和JSON格式 |
filesizeformat | {{ value |filesizeformat }} | 格式化value,使其成為易讀的檔案大小,例如13KB、4.1MB等 |
first | {{ value |first }} | 返回列表中的第一個Item,例如,如果value是列表['a','b','c'],那麼輸出將是'a' |
floatformat | {{ value |floatformat }}{{ value |floatformat:arg }} | 對資料進行四捨五入處理,引數arg是保留小數位,可以是正數或負數,如{{ value | floatformat:"2" }}是保留兩位小數。若無引數arg,預設保留1位小數,如{{ value | floatformat }} |
get_digit | {{ value |get_digit:"arg" }} | 如果value是123456789,arg是2,那麼輸出的是8 |
iriencode | {{ value |iriencode }} | 如果value中有非ASCII字元,那麼將其轉化成URL中適合的編碼 |
join | {{ value |join:"arg"}} |
使用指定的字串連線一個list,作用如同Python的str.join(list) |
last | {{ value |last }} | 返回列表中的最後一個Item |
length | {{ value |length }} | 返回value的長度 |
length_is | {{ value | length_is:"arg" }} | 如果value的長度等於arg,例如:value是['a','b','c'],arg是3,那麼返回True |
linebreaks | {{ value | linebreaks }} | value中的"\n"將被<br/>替代,並且將整個value使用<p>包圍起來,從而適合HTML的格式 |
linebreaksbr | {{ value | linebreaksbr }} | value中的"\n"將被<br/>替代 |
timeuntil | {{ value | timeuntil }} | 返回value距離當前日期的天數和小時數 |
linenumbers | {{ value | linenumbers}} | 為顯示的文字新增行數 |
ljust | {{ value | ljust }} | 以左對齊方式顯示value |
center | {{ value | center }} | 以居中對齊方式顯示value |
rjust | {{ value | rjust }} | 以右對齊方式顯示value |
lower | {{ value | lower }} | 將一個字串轉換成小寫形式 |
make_list | {{ value | make_list }} | 將value轉換成list。例如value是Joel,輸出[u'J',u'o',u'e',u'l'];如果value是123,那麼輸出是[1,2,3] |
pluralize |
{{ value | pluralize }}或{{ value |pluralize:" es " }} 或{{ value |pluralize:"y,ies }} |
將value返回英文複數形式 |
random | {{ value | random }} | 從給定的list中返回一個任意的Item |
removetags | {{ value | removetags:"tag1 tag2 tag3..." }} | 刪除value中tag1,tag2...的標籤 |
safe | {{ value | safe }} | 關閉HTML轉義,告訴Django這段程式碼是安全的,不必轉義 |
safeseq | {{ value | safeseq }} | 與上述safe基本相同,但有一點不同;safe針對字串,而safeseq針對多個字串組成的sequence |
slice | {{ some_list | slice:":2" }} | 與Python語法中的slice相同,":2"表示擷取前兩個字元,此過濾器可用於中文或英文 |
slugify | {{ value | slugify }} | 將value轉換成小寫形式,同時刪除所有分單詞字元,並將空格變成橫線。例如:value是Joel is a slug,那麼輸出的將是joel-is-a-slug |
striptags | {{ value | striptags }} | 刪除value中的所有HTML標籤 |
time | {{ value | time:"H:i" }}或{{ value |time }} | 格式化時間輸出,如果time後面沒有格式化引數,那麼輸出按照預設設定的進行 |
truncatewords | {{ value | truncatewords:2 }} | 將value進行單詞擷取處理,引數2代表擷取前兩個單詞,此過濾器值可用於英文擷取。如value是Joel is a slug那麼輸出將是:Joel is |
upper | {{ value | upper }} | 轉換一個字串為大寫形式 |
urlencode | {{ value | urlencode }} | 將字串進行URLEncode處理 |
urlize | {{ value | urlize }} | 將一個字串中的URL轉換成可點選的形式。如果value是Check out www.baidu.com,那麼輸出的將是:Check out <a href="http://www.baidu.com">www.baidu.com</a> |
wordcount | {{ value | wordcount }} | 返回字串中單詞的數目 |
wordwrap | {{ value | wordwrap:5 }} | 按照指定長度的分割字串 |
timesince | {{ value | timesince:arg }} | 返回引數arg到value的天數和小時數。如果arg是一個日期例項,表示2006-06-01午夜,而value表示2006-06-01早上8點,那麼輸出結果返回"8 hours" |
5.3.2自定義過濾器。
1. 主目錄下新建user_defined資料夾,裡面新增templatetags和__init__.py檔案,其中templatetags資料夾下建立myfilter.py檔案,如下圖:
templatetags用於存放自定義過濾器的程式碼檔案,該資料夾也可以存放在專案的APP中,但必須注意的是,資料夾的命名必須為templatetags,否則Django在執行的時候無法識別自定義過濾器。myfilter.py檔案,該檔案是編寫自定義過濾器的實現程式碼。
2.完成過濾器的目錄搭建,接著是配置過濾器的資訊,在配置檔案settings.py的INSTALLED_APPS裡面新增user_defined。當專案啟動時,Django會從INSTALLED_APPS的配置中查詢過濾器,若過濾器設定在index的目錄下,則只需在INSTALLED_APPS中配置index即可,如下:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'index', 'user_defined', ]
3.編寫自定義過濾器的實現程式碼,在myfilter.py中新增以下程式碼:
from django import template # 註冊過濾器 register = template.Library() # 宣告並定義過濾器 @register.filter def myreplace(value, agrs): oldValue = agrs.split(':')[0] newValue = agrs.split(':')[1] return value.replace(oldValue, newValue)
上述程式碼用於實現HTML模板的字串替換功能,與Python的replace函式相同,過濾器說明如下:
1、首先匯入模板功能template,通過template宣告Library物件,將物件賦值給變數register,這一過程稱為註冊過濾器。
2、過濾器以函式的形式實現,在函式前使用register.filter裝飾器來表示該函式是一個過濾器,函式名可自行命名。
3、函式引數可設定一個或兩個,如上述的引數分別是value和agrs,引數value是HTML模板的變數,引數agrs是過濾器函式定義的函式引數。
4、過濾器函式最後必須將處理結果返回,否則在使用過程中會出現異常資訊。
4.最後在HTML模板中使用我們自定義的過濾器,以index.html模板的title為例,程式碼如下:
{% load myfilter %} <!DOCTYPE html> <html> <head> <title>{{ title|myreplace:'首頁:我的首頁' }}</title> <meta charset="utf-8"> {% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static "css/hw_index.css" %}" > <link rel="icon" href="{% static "img/hw.ico" %}"> <script src="{% static "js/hw_index.js" %}"></script> </head>
在HTML模板中使用自定義的過濾器可以分為兩大步驟,說明如下:
1、{% load myfilter %},匯入templatetags資料夾的myfilter.py檔案中所定義的功能,用來告訴Django在那個地方可以找到自定義過濾器。
2、{{ title | myreplace:'首頁:我的首頁' }},把變數title含有"首頁"的內容替換成"我的首頁"。其中,myreplace是過濾器的函式名,”首頁:我的首頁"是函式引數agrs的值,函式引數value的值為模板變數title的值。執行結果如下:
00000