再Jinjia2中過濾器是一種轉變變量輸出內容的技術。··過濾器通過管道符號“|與變量鏈接,並且可以通過圓括號傳遞參數” 。舉例說明:
{{my_variable|default('my_variable is not defined')}}
my_variable 為變量,default為過濾器,my_variable is not defined是過濾器的參數。default過濾器的含義是:判斷被轉換的變量是否被定義過,如果沒有被定義,則用字符串參數替換被轉換的變量。
下面列出幾個常用的過濾器
字符串操作:
{# 當變量未定義時,顯示默認字符串,可以縮寫為d #} <p>{{ name | default('No name', true) }}</p> {# 單詞首字母大寫 #} <p>{{ 'hello' | capitalize }}</p> {# 單詞全小寫 #} <p>{{ 'XML' | lower }}</p> {# 去除字符串前后的空白字符 #} <p>{{ ' hello ' | trim }}</p> {# 字符串反轉,返回"olleh" #} <p>{{ 'hello' | reverse }}</p> {# 格式化輸出,返回"Number is 2" #} <p>{{ '%s is %d' | format("Number", 2) }}</p> {# 關閉HTML自動轉義 #} <p>{{ '<em>name</em>' | safe }}</p> {% autoescape false %} {# HTML轉義,即使autoescape關了也轉義,可以縮寫為e #} <p>{{ '<em>name</em>' | escape }}</p> {% endautoescape %}
數值操作
{# 四舍五入取整,返回13.0 #} <p>{{ 12.8888 | round }}</p> {# 向下截取到小數點后2位,返回12.88 #} <p>{{ 12.8888 | round(2, 'floor') }}</p> {# 絕對值,返回12 #} <p>{{ -12 | abs }}</p>
列表操作
{# 取第一個元素 #} <p>{{ [1,2,3,4,5] | first }}</p> {# 取最后一個元素 #} <p>{{ [1,2,3,4,5] | last }}</p> {# 返回列表長度,可以寫為count #} <p>{{ [1,2,3,4,5] | length }}</p> {# 列表求和 #} <p>{{ [1,2,3,4,5] | sum }}</p> {# 列表排序,默認為升序 #} <p>{{ [3,2,1,5,4] | sort }}</p> {# 合並為字符串,返回"1 | 2 | 3 | 4 | 5" #} <p>{{ [1,2,3,4,5] | join(' | ') }}</p> {# 列表中所有元素都全大寫。這里可以用upper,lower,但capitalize無效 #} <p>{{ ['tom','bob','ada'] | upper }}</p>
字典列表操作
{% set users=[{'name':'Tom','gender':'M','age':20}, {'name':'John','gender':'M','age':18}, {'name':'Mary','gender':'F','age':24}, {'name':'Bob','gender':'M','age':31}, {'name':'Lisa','gender':'F','age':19}] %} {# 按指定字段排序,這里設reverse為true使其按降序排 #} <ul> {% for user in users | sort(attribute='age', reverse=true) %} <li>{{ user.name }}, {{ user.age }}</li> {% endfor %} </ul> {# 列表分組,每組是一個子列表,組名就是分組項的值 #} <ul> {% for group in users|groupby('gender') %} <li>{{ group.grouper }}<ul> {% for user in group.list %} <li>{{ user.name }}</li> {% endfor %}</ul></li> {% endfor %} </ul> {# 取字典中的某一項組成列表,再將其連接起來 #} <p>{{ users | map(attribute='name') | join(', ') }}</p>
自定義過濾器
內置的過濾器不滿足需求怎么辦?自己寫唄。過濾器說白了就是一個函數嘛,我們馬上就來寫一個。回到Flask應用代碼中:
我們定義了一個”double_step_filter”函數,返回輸入列表的偶數位元素(第0位,第2位,..)。怎么把它加到模板中當過濾器用呢?Flask應用對象提供了”add_template_filter”方法來幫我們實現。我們加入下面的代碼:
函數的第一個參數是過濾器函數,第二個參數是過濾器名稱。然后,我們就可以愉快地在模板中使用這個叫”double_step”的過濾器了:
Flask還提供了添加過濾器的裝飾器”template_filter”,使用起來更簡單。下面的代碼就添加了一個取子列表的過濾器。裝飾器的參數定義了該過濾器的名稱”sub”。
我們在模板中可以這樣使用它:
Flask添加過濾器的方法實際上是封裝了對Jinja2環境變量的操作。上述添加”sub”過濾器的方法,等同於下面的代碼。
我們在Flask應用中,不建議直接訪問Jinja2的環境變量。如果離開Flask環境直接使用Jinja2的話,就可以通過”jinja2.Environment”來獲取環境變量,並添加過濾器。
完整代碼如下:
from flask import Flask,render_template app = Flask(__name__) @app.route('/glq') @app.route('/glq/<name>') def hello(name=None): return render_template('glq.html', name=name) ########## Add Filter ########## def double_step_filter(l): return l[::2] app.add_template_filter(double_step_filter, 'double_step') @app.template_filter('sub') def sub(l, start, end): return l[start:end] #app.jinja_env.filters['sub'] = sub if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)
html端代碼為:
<!DOCTYPE html> <title>Hello Sample</title> {% if name %} <h1>Hello {{ name | upper | truncate(3, True) }}!</h1> {% else %} <h1>Hello World!</h1> {% endif %} {# 字符串操作 #} {# 當變量未定義時,顯示默認字符串 #} <p>{{ name | default('No name', true) }}</p> {# 單詞首字母大寫 #} <p>{{ 'hello' | capitalize }}</p> {# 單詞全小寫 #} <p>{{ 'XML' | lower }}</p> {# 去除字符串前后的空白字符 #} <p>{{ ' hello ' | trim }}</p> {# 字符串反轉,返回"olleh" #} <p>{{ 'hello' | reverse }}</p> {# 格式化輸出,返回"Number is 2" #} <p>{{ '%s is %d' | format("Number", 2) }}</p> {# 關閉HTML自動轉義 #} <p>{{ '<em>name</em>' | safe }}</p> {% autoescape false %} {# HTML轉義,即使autoescape關了也轉義 #} <p>{{ '<em>name</em>' | escape }}</p> {% endautoescape %} {# 數值操作 #} {# 四舍五入取整,返回13.0 #} <p>{{ 12.8888 | round }}</p> {# 向下截取到小數點后2位,返回12.88 #} <p>{{ 12.8888 | round(2, 'floor') }}</p> {# 絕對值,返回12 #} <p>{{ -12 | abs }}</p> {# 列表操作 #} {# 取第一個元素 #} <p>{{ [1,2,3,4,5] | first }}</p> {# 取最后一個元素 #} <p>{{ [1,2,3,4,5] | last }}</p> {# 返回列表長度 #} <p>{{ [1,2,3,4,5] | length }}</p> {# 列表求和 #} <p>{{ [1,2,3,4,5] | sum }}</p> {# 列表排序,默認為升序 #} <p>{{ [3,2,1,5,4] | sort }}</p> {# 合並為字符串,返回"1 | 2 | 3 | 4 | 5" #} <p>{{ [1,2,3,4,5] | join(' | ') }}</p> {# 列表中所有元素都全大寫。這里可以用upper,lower,但capitalize無效 #} <p>{{ ['tom','bob','ada'] | upper }}</p> {# 字典列表操作 #} {% set users=[{'name':'Tom','gender':'M','age':20}, {'name':'John','gender':'M','age':18}, {'name':'Mary','gender':'F','age':24}, {'name':'Bob','gender':'M','age':31}, {'name':'Lisa','gender':'F','age':19}] %} {# 按指定字段排序,這里設reverse為true使其按降序排 #} <ul> {% for user in users | sort(attribute='age', reverse=true) %} <li>{{ user.name }}, {{ user.age }}</li> {% endfor %} </ul> {# 列表分組,每組是一個子列表,組名就是分組項的值 #} <ul> {% for group in users|groupby('gender') %} <li>{{ group.grouper }}<ul> {% for user in group.list %} <li>{{ user.name }}</li> {% endfor %}</ul></li> {% endfor %} </ul> {# 取字典中的某一項組成列表,再將其連接起來 #} <p>{{ users | map(attribute='name') | join(', ') }}</p> {# tojson #} <script type="text/javascript"> var users = {{ users | tojson | safe }}; console.log(users[0].name); </script> {% filter upper %} This is a Flask Jinja2 introduction. {% endfilter %} {# 自定義過濾器 #} {# 返回[1,3,5] #} <p>{{ [1,2,3,4,5] | double_step }}</p> {# 返回[2,3,4] #} <p>{{ [1,2,3,4,5] | sub(1,4) }}</p>
運行效果圖: