天天看點

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

點選檢視第一章 點選檢視第二章

第3章Jinja 2模闆引擎

在Flask中通常使用Jinja 2模闆引擎來實作複雜的頁面渲染。Jinja 2被認為是靈活、快速安全的模闆引擎技術,被廣泛使用。Jinja 2的設計思想來源于Django模闆引擎, 它功能強大、速度 快,并且提供了可選的沙箱模闆執行環境安全保證機制,具有沙箱中執行、強大的HTML轉義系統、模闆繼承等諸多優點。本章主要介紹Jinja 2模闆引擎的基本結構、基本使用方法。

本章主要涉及的知識點有:

  • 如何使用Flask渲染模闆;
  • 在模闆中傳遞一個或多個參數;
  • if語句在模闆中的使用;
  • for語句在模闆中的使用。

3.1模闆引擎概述及簡單使用

随着不同終端(個人PC、平闆電腦,手機、移動穿戴裝置等)的興起,開發人員在越來越多地思考:如何寫一份功能代碼(業務邏輯代碼),這份業務邏輯代碼能夠在響應式或非響應式裝置上都能使用。為了提升開發效率,開發人員開始高度重視前後端的分離,後端負責業務邏輯/資料通路,前端負責表現、互動邏輯,同一份業務邏輯代碼可應用于多個不同終端的視圖渲染。後端實際上實作的功能一般叫做業務邏輯,前端完成的功能一般叫做表現邏輯。如果把業務邏輯和表現邏輯混在一起,勢必造成系統耦合度高、代碼維護困難的現象,是以分離業務邏輯和表現邏輯,把變現邏輯交給視圖引擎,即網頁模闆,很有必要。

模闆實質上是一個靜态的包含HTML文法的全部或片段的文本檔案,也可包含由變量表示的動态部分。使用真實值替換網頁模闆中的變量,生成對應資料的HTML片段,這一過程稱為渲染。Flask提供了Jinja 2模闆引擎來渲染模闆,下面逐漸介紹其模闆渲染機制。

在PyCharm中建立一名稱為3-1的工程,在工程中templates的檔案夾下建立index.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

在工程中templates的檔案夾下建立user.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

  

app.py檔案的代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

 

01行表示導入Flask子產品;02行表示導入render_template子產品;03行表示Flask初始化;04行定義路由;05行定義視圖函數;06行使用render_template()方法渲染模闆;07行定義路由;08行定義視圖函數;09行使用render_template()方法渲染模闆;10行表示當子產品被直接運作時,代碼将被運作,當子產品是被導入時,代碼不被執行;11行表示開啟調試模式。

運作程式,得到如3.1圖所示結果。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

Flask通過render_template()函數來實作模闆的渲染。要使用Jinja 2模闆引擎,需要使用from flask import render_template指令導入render_template函數。在視圖函數的return方法中,render_template()函數的首個參數聲明使用哪一個模闆檔案。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.2向模闆中傳遞參數

Flask提供Jinja 2模闆引擎來渲染模闆的同時,還可以将程式中的參數或變量值傳遞給指定的模闆進行渲染。

在PyCharm中建立一名稱為3-2的工程,在工程中的templates檔案夾下建立index.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

在工程中templates檔案夾下建立user.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

01行表示導入Flask子產品;02行表示導入render_template子產品;03行表示Flask初始化;04行表示定義路由;05行表示定義視圖函數;06行渲染模闆;07行定義路由;08行表示定義視圖函數;09行表示渲染模闆并向模闆傳遞參數;10行表示當子產品被直接運作時,代碼将被運作,當子產品被導入時,代碼不被執行。

運作程式,得到如圖3.2所示結果。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

render_template()函數第一個參數是指定模闆檔案的名稱,比如這裡的index.html和user.html。render_template( )函數的第二個參數為可選項,可以為空。比如index()視圖函數中的render_template('index.html'),這裡第二個參數為空。第二個參數不為空的話,一般用于向模闆中傳遞變量。這裡傳遞變量,一般是以鍵值對方式進行的。

01 @app.route('/')
  02 def index():
  03 title = 'python的鍵值對'
  04 author='tom_jack'
  05 return render_template('index.html', var1=title, var2=author)           

用上述代碼替換index()視圖函數代碼,在index.html的body塊兒區域增加下面的代碼:

01 <body>
  02 {{ var1 }}<br> {#br表示網頁中的回車#}
  03 {{ var2 }}
  04 </body>           

再次運作程式,得到如圖3.3所示結果。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

模闆中接收變量值,需要把變量放在{{ }},比如{{ var1 }}等。模闆中如果要寫注釋,格式為{# #},比如這裡的{#br表示網頁中的回車#}。

如果視圖函數中有多個變量值都需要傳遞給模闆,可以使用**locals()方法,例如:

01 def index():    #定義index函數
  02   # return render_template('index.html')
  03  title = 'python的鍵值對'    #定義鍵值
  04  author = 'tom_jack'    #定義鍵值
  05  return render_template('index.html', **locals())    #渲染模闆并傳值           

實際上是将return render_template('index.html', var1=title, var2=author)這行代碼替換為return render_template('index.html', **locals())。将模闆檔案index.html中的{{ var1 }}

{{ var2 }}替換為{{ title }}

{{ author }}即可。

注意:在render_template()函數中,如果要給模闆傳遞全部的本地變量,可以使用**locals()方法,此時,在子產品中可以直接使用{{title}}和{{author}}來直接使用變量。

3.3模闆中的控制語句之if語句

在Jinja 2模闆引擎中也可以使用if和for循環控制語句,控制模闆渲染的方向。模闆引擎中,if和for語句中應該放到{% %}中。

本節我們首先看看模闆中的if語句如何使用。在前端的Jinja 2文法中,if可以進行判斷:是否存在參數,存在的參數是否滿足條件,其基本文法如下:

01 {% if condition %}    <!-- condition指的是條件-->
  02 {% else %}    <!-- 條件不滿足時-->
  03 {% endif %}    <!-- 結束if語句-->           

在PyCharm中建立一個名稱為3-3的工程。在工程中的templates檔案夾下建立index.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

app.py對應的代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

import random表示導入Python的随機庫,rand1=random.randint(0,1)表示産生0~1範圍内的整型數。在模闆中進行判斷,如果産生的資料為1,視為有效,如果産生的資料為0,視為無效資料。運作本項目代碼,結果如圖3.4所示。可以多次重新整理,看看輸出結果有何不同。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

在PyCharm中建立一名稱為3-4的工程。在工程中的templates檔案夾下建立index.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

app.py檔案内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

運作項目代碼,運作結果如圖3.5所示。

在模闆中,盡量少使用多層嵌套的 if…else…語句,往往會因為縮進出現這樣或那樣的問題。盡量多用if…elif…else…的結構(即多個elif),這一系列條件判斷會從上到下依次判斷,如果某個判斷為True,執行完對應的代碼塊,後面的條件判斷就會直接忽略,不再執行。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.4模闆中的控制語句之for語句

首先,我們回顧一下Python中的for循環語句。for循環語句是Python中的一個循環控制語句,任何有序的序列對象内的元素都可以周遊,比如字元串、清單、元組等可疊代對像。for循環的文法格式如下:  

for 目标 in 對象:
      循環體           

比如,使用for循環一個字元串,輸出字元串中每位字元的操作方法如下:

01  #encoding:utf-8    #指定編碼
  02  str='www.google.com'    #定義字元串
  03  for str1 in str:     #for循環進行周遊
  04  print(str1)     #列印輸出           

運作程式,螢幕上可以輸出www.google.com中每一個字元。那麼模闆中的for循環又該如何使用呢?模闆中的for語句定義如下:

01 {% for 目标 in對象 %}
  02 <p>目标</p>
  03 {% endfor %}           

Jinja 2中for循環内置常量:

  • loop.index:目前疊代的索引(從1開始);
  • loop.index0:目前疊代的索引(從0開始);
  • loop.first:是否是第一次疊代,傳回True或False;
  • loop.last是否是最後一次疊代,傳回True或False;
  • loop.length:傳回序列的長度。
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

下面以視圖函數定義一個字典goods,在模闆中使用for循環渲染輸出。在PyCharm中建立一名稱為3-5的工程。在工程中的templates檔案夾下建立shop.html檔案,代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

上面的代碼實作了一個靜态頁面,代碼中定義了一個表格,表格分為5行2列進行顯示,其中,第1行用來顯示表格“商品名稱”及“商品價格”等内容。

app.py檔案的内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

在hello_world視圖函數中定義一清單goods,其屬性主要有name和price,用for語句将其周遊出來。運作程式,運作結果如圖3.6所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.5Flask的過濾器

過濾器本質上是一個轉換函數,有時候我們不僅需要輸出變量的值,還需要把某個變量的值修改後再顯示出來,而在模闆中不能直接調用Python中的某些方法,這麼這就用到了過濾器。

3.5.1常見過濾器

1.與字元串操作相關的過濾器

<p>{{name|default('None',true)}</p>           

其中,name為變量名,如果name為空,則用None這個值去替換name。

-

<p>{{'hello'|capitalize}}</p>           

将字元串hello轉化成Hello,實作首字母大寫的目的。

<p>{{'HELLO'|lowere}}</p>           

将字元HELLO全部轉為小寫。

<p>{{'hello'|replace('h','x')}}</p>           

将hello中的字母h替換成x。

2.對清單進行操作相關的過濾器

  • {{[01,80,42,44,77]|first}}

    取得清單中的首個元素01。

  • {{[01,80,42,44,77]|last}}

    取得清單中的最後一個元素77。

  • {{[01,80,42,44,77]|count}}

    取得清單中的元素個素,統計個數為5,count也可以使用length替換。

  • {{[01,80,42,44,77]|sort}}

    清單中的元素重新排序,預設按照升序進行排序。

  • {{[01,80,42,44,77]|join(','}}

    将清單中的元素合并為字元串,傳回1,80,42,44,77。

3.對數值進行操作相關的過濾器

  • {{18.8888|round}}

    四舍五入取得整數,傳回19.0。

  • {{18.8888|round(2,’floor’)}}

    保留小數點後2位,傳回結果為18.88。

  • {{-2|abs}}

求絕對值運算,傳回結果為2。

下面以清單中的每間隔2行換顔色為例,詳細說明模闆中過濾器的使用方法。

在PyCharm中建立一名稱為3-6的工程。在工程中的templates檔案夾下建立index.html和app.py檔案,index.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.5.2自定義過濾器

内置的過濾器不滿足需求怎麼辦?過濾器的實質就是一個轉換函數,我們其實完全可以寫出屬于自己的自定義過濾器。

通過調用應用程式執行個體的 add_template_filter 方法實作自定義過濾器。該方法第一個參數是函數名,第二個參數是自定義的過濾器名稱。

有一個商品清單頁,要求每3行輸出一條分割線。在PyCharm中建立一名稱為3-7的工程。在工程中的templates檔案夾下建立index.html和app.py檔案,index.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

上面的代碼對傳遞過來的清單進行周遊,每3行輸出一條分割線,分割線的樣式由07~13行所對應的代碼定義。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

02~05行導入相應子產品,有非UTF-8編碼範圍内的字元時就要使用sys.setdefaultencoding()方法予以修正。04行表示Flask初始化;05行表示定義路由;06行定義視圖函數;08~12行定義清單goods;13行表示渲染模闆,并向模闆傳遞參數;14行定義函數;15、16行表示每間隔3行傳回一個line;19行表示使用自定義過濾器添加CSS。

3.6 宏的定義及使用

Jinja 2中的宏功能有些類似于傳統程式語言中的函數,它跟Python中的函數類似,可以傳遞參數,但是不能有傳回值,可以将一些經常用到的代碼片段放到宏中,然後把一些不固定的值抽取出來作為一個變量。

3.6.1 宏的定義

宏(Macro),有聲明和調用兩個部分。讓我們先聲明一個宏:

01 <!--定義宏-->
  02 {% macro input(name, type='text', value= ' ') -%}
  03 ????<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
  04 {%- endmacro %}           

上面的代碼定義了一個宏,定義宏要加macro,宏定義結束要加endmacro标志。宏的名稱就是input,它有3個參數,分别是name、type和value,後兩個參數有預設值。我們可以使用表達式來調用這個宏:

01 <!--調用宏-->
  02 {{ input('username')}}
  03 {{ input('password',type='password')}}           

在Pycharm中建立一名為3-8的工程。在工程中templates的檔案夾下建立index.html檔案,index.html代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

執行網頁後,生成對應的代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

上面的代碼定義了一個宏,這個宏有3個參數,分别是name、type和value,然後用這個宏定義了兩個文本輸入框,定義了一個送出按鈕。

app.py檔案中需要引入模闆檔案,如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

01行導入Flask和render_template子產品;02行表示Flask初始化;03行表示定義路由;04行表示定義視圖函數;05行渲染模闆;06行表示當子產品被直接運作時,代碼将被運作,當子產品是被導入時,代碼不被執行;07行表示開啟調試模式。

運作上面的程式,結果如圖3.7所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.6.2 宏的導入

一個宏可以被不同的模闆使用,是以我們建議将其聲明在一個單獨的模闆檔案中。需要使用時導入即可,而導入的方法類似于Python中的import。我們把3.6.1節中的宏定義部分單獨放在一個檔案中。

在Pycharm中建立一名稱為3-9的工程。在工程中的templates檔案夾下建立index.html檔案和form.html檔案。index.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

form.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

上面的代碼定義了一個宏,定義宏要加macro,宏定義結束要加endmacro标志。宏的名稱就是input,它有3個參數,分别是name、type和value,後兩個參數有預設值。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

01行表示導入Flask及render_template子產品;02行表示Flask初始化;03行表示定義路由;04行定義視圖函數;05行渲染模闆。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.6.3 include的使用

宏檔案中引用其他宏,可以使用include語句。include語句可以把一個模闆引入到另外一個模闆中,類似于把一個模闆的代碼複制到另外一個模闆的指定位置。下面通過一個執行個體來說明。

在PyCharm中建立一個名為3-10的工程。在工程中的templates檔案夾下建立index.html檔案、header.html檔案及footer.html檔案。index.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

header.html檔案内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

footer檔案内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

01行表示導入Flask及render_template子產品;02行表示Flask初始化;03行定義路由;04行定義視圖函數;05行表示渲染模闆。

include把一個模闆的代碼複制到另外一個模闆的指定位置,這裡的{% include ''header.html'' %}和{% include ''footer.html'' %}把頭檔案和尾部檔案引入到index.html檔案中。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.7 set和with語句的使用

set與with語句都可以在Jinja 2中定義變量并賦予值。set定義的變量在整個模闆範圍内都有效,with關鍵字在定義變量并指派的同時,限制了with定義變量的作用範圍。

首先介紹一下set關鍵字的使用方法:

(1)給變量指派:

{% set telephone ='1388888888' %}           

(2)給清單或數組指派:

{% set nav = [('index.html', 'index'), ('product.html', 'product)] %}           

可以在模闆中使用{{ telephone }}和{{ nav }}來引用這些定義的變量。

接下來介紹with關鍵字的使用方法,例如:

{% with pass = 60 %}
   {{ pass }}
   {% endwith %}           

with定義的變量的作用範圍在{% with %}和{% endwith %}代碼塊内,在模闆的其他地方,引用此變量值無效。

在PyCharm中建立一名為3-11的工程。在工程中templates的檔案夾下建立index.html檔案,index.html檔案代碼如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

運作上面的工程,結果如圖3.8所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.8 靜态檔案的加載

靜态檔案的加載一般需要先建立檔案夾static,在檔案夾下再建立css、js和images檔案夾,在這些檔案夾中存放css、js、images,同時要需要使用'url_for'函數。

在PyCharm中建立一個名為3-12的工程。找到static檔案夾,在此檔案夾下再建立css、js和images這3個檔案夾,目錄結構如圖3.9所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

在templates目錄下建立一個名為index.html的檔案, 在app.py的視圖函數中使用return render_template('index.html')方法來渲染模闆。下面分别給出加載JS、圖檔和CSS的方法。

(1)加載JS檔案

在靜态檔案index.html中,在之前引入jquery-3.3.1.js檔案,具體代碼如下:

<script src="{{ url_for('static', filename='js/jquery-3.3.1/jquery-3.3.1.js') }}">
  </script>           

可以使用下面代碼測試jquery-3.3.1.js檔案是否加載成功。

<script>
      if(jQuery) {
          alert('jQuery已加載!');
      }
      else {
          alert('jQuery未加載!');
      }
  </script>           

通過測試,可以發現通過上述方法可以正常加載js檔案。這裡使用到了url_for()函數來實作。事實上,還可以通過下面代碼實作:

<script type="text/javascript" src="static/js/jquery-3.3.1/jquery-3.3.1.js">
  </script>           

不過,一般建議使用url_for()函數形式。

(2)加載圖檔檔案。

加載圖檔,可以使用下述代碼實作:

<img src="{{ url_for('static', filename='images/car.jpg') }}"></img>           

(3)加載CSS檔案。

加載外部CSS檔案,可以使用下述代碼實作:

<link rel="stylesheet" href="{{ url_for('static',filename='css/car.css') }}">           

car.css的代碼如下:

.img{
  BORDER-RIGHT: #000 1px solid; BORDER-TOP: #000 1px solid; MARGIN: 10px 0px; BORDER-LEFT: #000 1px solid; BORDER-BOTTOM: #000 1px solid
          }           

在index.html檔案中添加如下代碼:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

運作上述代碼,效果如圖3.10所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.9 模闆的繼承

一個系統網站往往需要統一的結構,這樣看起來比較“整潔”。比如,一個頁面中都有标題、内容顯示、底部等幾個部分。如果在每一個網頁中都進行這幾部分的編寫,那麼整個網站将會有很多備援部分,而且編寫的網頁程式也不美觀。這時可以采用模闆繼承,即将相同的部分提取出來,形成一個base.html,具有這些相同部分的網頁通過繼承base.html來得到對應的子產品。

1.模闆的繼承文法

模闆的繼承文法如下:

{% extends “模闆名稱” %}           

2.塊的概念

模闆繼承包含基本模闆和子模闆。其中,基本模闆裡包含了網站裡基本元素的基本骨架,但是裡面有一些空的或不完善的塊(block)需要用子模闆來填充。

在父模闆中:  

  …
  {% block block的名稱 %}
  {% endblock %}
  …            

在子模闆中:

…
  {% block block的名稱 %}
  子模闆中代碼
  {% endblock %}
  …           

在PyCharm中建立一個名為3-13的工程。在templates目錄中建立index.html、base.html和product.html 3個靜态檔案。base.html檔案作為基類,index.html和product.html檔案作為子類,子類去繼承基類的基本内容。

base.html檔案内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

index.html檔案内容如下:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

product.html檔案的内容:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

預設情況下,子模闆如果實作了父模闆定義的block,那麼子模闆block中的代碼就會覆寫父模闆中的代碼。如果想要在子模闆中仍然保持父摸闆中的代碼,那麼可以使用{{super()}}來實作,如index.html中{% block body %}{% endblock %}代碼塊中使用了{{ super() }}方法,運作結果如圖3.11所示:

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

如果想要在一個block中調用其他block中的代碼,可以通過{{self.其他block名稱()}}實作。比如product.html檔案中的

{{ self.title() }}

方法。運作此代碼,結果如圖3.12所示。

帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎
帶你讀《Python Flask Web開發入門與項目實戰》之三:Jinja 2模闆引擎第3章Jinja 2模闆引擎

3.10 溫 故 知 新

1.學完本章内容後,讀者需要回答:

(1)什麼是模闆?

(2)模闆中如何寫注釋?

(3)模闆中如何使用if語句?

(4)模闆中如何使用for語句?

2.在下一章中将會學習:

(1)路由函數的使用。

(2)裝飾器的基本使用。

(3)藍圖的定義和基本使用。

3.11 習 題

通過下面的習題來檢驗本章的學習情況,習題答案請參考本書配套資源。

1.使用for語句,建立一個工程,列印出九九乘法表。

2.在視圖函數中定義一個字典books,請在模闆中周遊出字典的所有屬性。