Python之 jinja2模板淺析

目錄

前言

1. jinja2介紹

1.1 jinja2的優點

1.2 安裝jinja2

2. jinja2語法

2.1 基本語法

2.2 jinja2變量

2.3 jinja2中的過濾器

3. jinja2的控制結構

3.1 jinja2的for循環

4. jinja2的宏

5. jinja2的繼承和Super函數

6. 利用jinja2進行渲染

6.1 基本使用方法

6.2 PackageLoader

6.3 FileSystemLoader


前言

  要了解jinja2,那麼需要先理解模板的概念。模板在Python的web開發中廣泛使用,它能夠有效的將業務邏輯和頁面邏輯分開,使代碼可讀性增強、並且更加容易理解和維護。

  模板簡單來說就是一個其中包涵佔位變量表示動態部分的文件,模板文件在經過動態賦值後,返回給用戶。  --> 可以理解爲渲染

  python中自帶一個簡單的模板,就是string提供的。

1

2

3

4

5

6

7

>>> import string

>>> a = string.Template('$who is $role')

>>> a.substitute(who='daxin',role='Linux')

'daxin is Linux'

>>> a.substitute(who='daxin',role='cat')

'daxin is cat'

>>>

  Python自帶的模板功能極其有限,如果我們想要在模板中使用控制語句,和表達式,以及繼承等功能的話,就無法實現了。

  目前主流的模板系統,最常用的就是jinja2和mako

1. jinja2介紹

  jinja2是Flask作者開發的一個模板系統,起初是仿django模板的一個模板引擎,爲Flask提供模板支持,由於其靈活,快速和安全等優點被廣泛使用。

1.1 jinja2的優點

  jinja2之所以被廣泛使用是因爲它具有以下優點:

  1. 相對於Template,jinja2更加靈活,它提供了控制結構,表達式和繼承等。
  2. 相對於Mako,jinja2僅有控制結構,不允許在模板中編寫太多的業務邏輯。
  3. 相對於Django模板,jinja2性能更好。
  4. Jinja2模板的可讀性很棒。

1.2 安裝jinja2

  由於jinja2屬於第三方模塊,首先需要對其進行安裝

1

pip3 install jinja2

  測試模板是否安裝成功

1

2

3

4

python -"import jinja2"

 

# 沒有報錯就表示安裝成功

# 必須用雙引號"

2. jinja2語法

  作爲一個模板系統,它還提供了特殊的語法,我們按照它支持的語法進行編寫之後,就能使用jinja2模塊進行渲染。

2.1 基本語法

   在jinja2中,存在三種語法:

  1. 控制結構 {% %}
  2. 變量取值 {{ }}
  3. 註釋 {# #}

  下面是一個簡單的jinja2例子

1

2

3

4

5

6

7

{# This is jinja code

 

    {% for file in filenames %}

    ...

    {% endfor %}

 

#}

  可以看到,for循環的使用方式和Python比較類似,但是沒有了句尾的冒號,另外需要使用endfor作爲結尾,其實在jinja2中,if也是一樣的,結尾需要使用endif。

2.2 jinja2變量

  jinja2模板中使用 {{ }} 語法表示一個變量,它是一種特殊的佔位符。當利用jinja2進行渲染的時候,它會把這些特殊的佔位符進行填充/替換,jinja2支持python中所有的Python數據類型比如列表、字段、對象等。

1

2

3

<p>this is a dicectory:{{ mydict['key'] }} </p>

<p>this is a list:{{ mylist[3] }} </p>

<p>this is a object:{{ myobject.something() }} </p>

2.3 jinja2中的過濾器

  變量可以通過“過濾器”進行修改,過濾器可以理解爲是jinja2裏面的內置函數和字符串處理函數。

  常用的過濾器有:

過濾器名稱     說明    
safe  渲染時值不轉義
capitialize  把值的首字母轉換成大寫,其他子母轉換爲小寫
 lower  把值轉換成小寫形式 
 upper  把值轉換成大寫形式 
 title  把值中每個單詞的首字母都轉換成大寫
 trim  把值的首尾空格去掉
 striptags  渲染之前把值中所有的HTML標籤都刪掉
join   拼接多個值爲字符串
 replace  替換字符串的值
 round  默認對數字進行四捨五入,也可以用參數進行控制
int   把值轉換成整型

   那麼如何使用這些過濾器呢? 只需要在變量後面使用管道(|)分割,多個過濾器可以鏈式調用,前一個過濾器的輸出會作爲後一個過濾器的輸入。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

{{ 'abc' | captialize  }}

# Abc

 

{{ 'abc' | upper  }}

# ABC

 

{{ 'hello world' | title  }}

# Hello World

 

{{ "hello world" | replace('world','daxin') | upper }}

# HELLO DAXIN

 

{{ 18.18 | round | int }}

# 18

3. jinja2的控制結構

  jinja2中的if語句類似於Python的if語句,它也具有單分支,多分支等多種結構,不同的是,條件語句不需要使用冒號結尾,而結束控制語句,需要使用endif關鍵字。

1

2

3

4

5

6

7

{% if daxin.safe %}

daxin is safe.

{% elif daxin.dead %}

daxin is dead

{% else %}

daxin is okay

{% endif %}

3.1 jinja2的for循環

  jinja2中的for循環用於迭代Python的數據類型,包括列表,元組和字典。在jinja2中不存在while循環。

  迭代列表

1

2

3

4

5

<ul>

{% for user in users %}

<li>{{ user.username|title }}</li>

{% endfor %}

</ul>

  迭代字典

1

2

3

4

5

6

<dl>

{% for key, value in my_dict.iteritems() %}

<dt>{{ key }}</dt>

<dd>{{ value}}</dd>

{% endfor %}

</dl>

      當然也可以加入else語句,在循環正確執行完畢後,執行

      在for循環中,jinja2還提供了一些特殊的變量,用以來獲取當前的遍歷狀態:

變量 描述
loop.index 當前迭代的索引(從1開始)
loop.index0 當前迭代的索引(從0開始)
loop.first 是否是第一次迭代,返回bool
loop.last 是否是最後一次迭代,返回bool
loop.length 序列中的項目數量
loop.revindex 到循環結束的次數(從1開始)
loop.revindex0 到循環結束的次數(從0開始)

4. jinja2的宏

  宏類似於Python中的函數,我們在宏中定義行爲,還可以進行傳遞參數,就像Python中的函數一樣一樣兒的。

  在宏中定義一個宏的關鍵字是macro,後面跟其宏的名稱和參數等

1

2

3

4

5

{% macro input(name,age=18) %}   # 參數age的默認值爲18

 

 <input type='text' name="{{ name }}" value="{{ age }}" >

 

{% endmacro %}

  調用方法也和Python的類似

1

2

<p>{{ input('daxin') }} </p>

<p>{{ input('daxin',age=20) }} </p>

5. jinja2的繼承和Super函數

  jinja2中最強大的部分就是模板繼承。模板繼承允許我們創建一個基本(骨架)文件,其他文件從該骨架文件繼承,然後針對自己需要的地方進行修改。

  jinja2的骨架文件中,利用block關鍵字表示其包涵的內容可以進行修改。

  以下面的骨架文件base.html爲例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<!DOCTYPE html>

<html lang="en">

<head>

    {% block head %}

    <link rel="stylesheet" href="style.css"/>

    <title>{% block title %}{% endblock %} - My Webpage</title>

    {% endblock %}

</head>

<body>

<div id="content">{% block content %}{% endblock %}</div>

<div id="footer">

    {% block  footer %}

    <script>This is javascript code </script>

    {% endblock %}

</div>

</body>

</html>

  這裏定義了四處 block,即:head,title,content,footer。那怎麼進行繼承和變量替換呢?注意看下面的文件

1

2

3

4

5

6

7

8

9

10

11

12

{% extend "base.html" %}       # 繼承base.html文件

 

{% block title %} Dachenzi {% endblock %}   # 定製title部分的內容

 

{% block head %}

    {{  super()  }}        # 用於獲取原有的信息

    <style type='text/css'>

    .important { color: #FFFFFF }

    </style>

{% endblock %}   

 

# 其他不修改的原封不同的繼承

  PS: super()函數 表示獲取block塊中定義的原來的內容

6. 利用jinja2進行渲染

  jinja2模塊中有一個名爲Enviroment的類,這個類的實例用於存儲配置和全局對象,然後從文件系統或其他位置中加載模板。

6.1 基本使用方法

  大多數應用都在初始化的時候創建一個Environment對象,並用它加載模板。Environment支持兩種加載方式:

  • PackageLoader:包加載器
  • FileSystemLoader:文件系統加載器

6.2 PackageLoader

  使用包加載器來加載文檔的最簡單的方式如下:

1

2

3

4

5

from jinja2 import PackageLoader,Environment

env = Environment(loader=PackageLoader('python_project','templates'))    # 創建一個包加載器對象

 

template = env.get_template('bast.html')    # 獲取一個模板文件

template.render(name='daxin',age=18)   # 渲染

  其中:

  • PackageLoader()的兩個參數爲:python包的名稱,以及模板目錄名稱。
  • get_template():獲取模板目錄下的某個具體文件。
  • render():接受變量,對模板進行渲染

6.3 FileSystemLoader

  文件系統加載器,不需要模板文件存在某個Python包下,可以直接訪問系統中的文件。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章