1. 程式人生 > 實用技巧 >第5章深入模板

第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