1. 程式人生 > >Flask 學習系列(三)---Jinjia2使用過濾器

Flask 學習系列(三)---Jinjia2使用過濾器

ide 數位 指定字段 模板 小數 else capital 12px 效果圖

再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應用代碼中:

1 2 def double_step_filter(l): return l[::2]

我們定義了一個”double_step_filter”函數,返回輸入列表的偶數位元素(第0位,第2位,..)。怎麽把它加到模板中當過濾器用呢?Flask應用對象提供了”add_template_filter”方法來幫我們實現。我們加入下面的代碼:

1 app.add_template_filter(double_step_filter, ‘double_step‘)

函數的第一個參數是過濾器函數,第二個參數是過濾器名稱。然後,我們就可以愉快地在模板中使用這個叫”double_step”的過濾器了:

1 2 {# 返回[1,3,5] #} <p>{{ [1,2,3,4,5] | double_step }}</p>

Flask還提供了添加過濾器的裝飾器”template_filter”,使用起來更簡單。下面的代碼就添加了一個取子列表的過濾器。裝飾器的參數定義了該過濾器的名稱”sub”。

1 2 3 @app.template_filter(‘sub‘) def sub(l, start, end): return l[start:end]

我們在模板中可以這樣使用它:

1 2 {# 返回[2,3,4] #} <p>{{ [1,2,3,4,5] | sub(1,4) }}</p>

Flask添加過濾器的方法實際上是封裝了對Jinja2環境變量的操作。上述添加”sub”過濾器的方法,等同於下面的代碼。

1 app.jinja_env.filters[‘sub‘] = 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>

運行效果圖:

技術分享

Flask 學習系列(三)---Jinjia2使用過濾器