Flask模板和宏
- ==黃色標注部分重點注意==
- 一. Flask模板過濾器
- 1. Jinja2模板內置過濾器
- abs(value)
- default(value, default_value, boolean=false)
- escape(value)
- safe(value)
- first(value)、last(value)和length(value)
- lower(value)、upper(value)
- replace(value, old, new)
- truncate(value,length=255,killwords=False)
- striptags(value)
- wordcount(s)
- 其他過濾器
- 2. 自定義過濾器
黃色標注部分重點注意
一. Flask模板過濾器
1. Jinja2模板內置過濾器
?模板過濾器相當于是一個函式,把當前的變數傳入過濾器,過濾器根據自己的功能對變數進行相應的處理,再回傳對應的值,并將結果渲染到網頁中
?過濾器是通過管道符號| 來實作的
?例如:傳入變數name,{{ name|length }}將回傳變數name的長度
?當你修改完模板檔案后想要檔案自動更新并加載,需要配置引數app.config[‘TEMPLATE_AUTO_RELOAD’] = True即可實作
Jinja2中有許多內置過濾器,以后進行一一介紹:
abs(value)
作用:回傳傳入變數的絕對值(int型別)
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True # 模板修改后自動更新并加載
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html檔案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
</body>
</html>
網頁顯示:

將變數的值轉換成絕對值顯示在網頁中
default(value, default_value, boolean=false)
作用:如果當前變數沒有傳入值,則會使用引數中的變數值來代替
例如:name|default(‘jack’)中,如果name變數未在視圖函式中定義,則會使用jack來代替
引數boolean=false默認是在只有這個變數么有定義時的時候才會使用default中的默認值,如果想使用python的形式判斷是否為false,則可以傳遞boolean=true,或者使用or來替換
運行測驗:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...') }}</h2>
</body>
</html>
網頁顯示:

在視圖函式中未定義和傳入username引數,渲染給定的默認值,如果在視圖函式中定義username引數,則會渲染給定的引數對應的值
?可以在default()中傳入引數boolean=true,此時會根據Python的規則來判斷name的布林值是True還是False,如果判斷結果為True則渲染name的值,如果是False則渲染default()中給定的默認值
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username1': None,
'username2': 'Tony'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
index.html模板代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username1|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ username2|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
</body>
</html>
網頁顯示:

default()中加入引數boolean=true,username1為None,其布林值為False,所以會渲染default()中給定的值,username2為一個非空字串,對應的布林值為True,則會渲染username2對應的值
escape(value)
作用:轉義字符,會將<、>等特殊符號轉義成HTML中的符號,使其成為普通字串,避免渲染成HTML元素,
表示方式:content|escape或content|e
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'script': ' < script > alert("hello") < / script > '
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ script|escape}}</h2>
</body>
</html>
網頁顯示:

Flask模板并未將script變數對應的值渲染為Javascript代碼,而是當成普通的字串來渲染
網頁源代碼如下:

Jinja2在渲染時將特殊字符自動轉義,在flask中,默認是開啟了自動轉義的功能的,所以不使用escape過濾器也是可以的
這是Jinja2的一種安全機制,可以防止對頁面進行篡改、注入等操作
safe(value)
作用:如果開啟了全域轉義,那么safe過濾器會將變數的轉義關閉
表示方式:content_html|safe
在上個例子中,如果想要取消轉義,可以關閉escape過濾器,測驗如下:
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
{% autoescape off %}
<h2>{{script}}</h2>
{% endautoescape %}
</body>
</html>
網頁顯示:

使用safe過濾器也可以達到相同的效果,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ script|safe }}</h2>
</body>
</html>
網頁顯示與之前完全相同
?可以使用safe過濾器渲染HTML代碼
測驗如下:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'code': '<h3>但行好事,莫問前程</h3>'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ code|safe }}</h2>
</body>
</html>
網頁顯示:

first(value)、last(value)和length(value)
作用: first(value)回傳一個序列的第一個元素,例如:names|first
last(value)回傳一個序列的最后一個元素,例如:names|last
length(value)回傳一個序列或者字典的長度,例如:names|length
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'code': '<h3>但行好事,莫問前程</h3>',
'language': ['Python', 'Java', 'PHP', 'C#']
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ code|safe }}</h2>
<h2>{{ language|first }}</h2>
<h2>{{ language|last }}</h2>
<h2>{{ language|length }}</h2>
</body>
</html>
網頁顯示:

還可以嵌套過濾,求串列中某個字串的長度:
例如:
<h2>{{ language|first|length }}</h2>
lower(value)、upper(value)
作用: lower(value):將字串轉換為小寫
upper(value):將字串轉換為大寫
運行測驗:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ code|safe }}</h2>
<h2>{{ name|lower }}</h2>
<h2>{{ name|upper }}</h2>
</body>
</html>
網頁顯示:

replace(value, old, new)
作用: 將字串中old字串替換為new字串
運行測驗:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{name|replace('cx','fl')}}</h2>
</body>
</html>
網頁顯示:

truncate(value,length=255,killwords=False)
作用: 截取length長度的字串
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'title': '不亂于心,不困于情,不畏將來,不念過往,如此,安好'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{ title|truncate(length=12) }}</h2>
</body>
</html>
網頁顯示:

truncate()過濾器一般用于顯示較長的標題省略末尾一部分內容
?注意:
truncate()傳入的length必須大于等于3,因為3表示省略號3個點,大于3時剩下的顯示變數具體內容,小于3時渲染會報錯
striptags(value)
作用: 洗掉字串中所有的HTML標簽,如果出現多個空格,將替換成一個空格
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'script':'<script>alert("hello")</script>'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{script | striptags}}</h2>
</body>
</html>
網頁顯示:

由網頁顯示可得:標簽都被過濾掉,只顯示標簽內部內容
wordcount(s)
作用: 計算一個長字串中單詞的個數,以空格間隔為一個單詞
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'name': 'ycx',
'age': -16,
'username': 'Tony',
'address': '中國 陜西省 西安市 臨潼區'
}
return render_template('index.html', **context)
if __name__ == '__main__':
app.run(debug=True)
模板index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask過濾器</title>
</head>
<body>
<h1>首頁</h1>
<h2>{{ name }}</h2>
<h2>{{ age|abs }}</h2>
<h2>{{ username|default('這個人很懶,什么都沒有留下...',boolean=true) }}</h2>
<h2>{{script | striptags}}</h2>
<h2>{{ address}}</h2>
<h2>{{ address|wordcount }}</h2>
</body>
</html>
網頁顯示:

其他過濾器
?format(value,*arags,**kwargs)
格式化字串
例如:{{ “%s” - “%s”|format(‘Hello’,“World”) }}將輸出Hello - World
?join(value,d=‘xx’)
將一個序列用d引數的值拼接成字串
?int(value)
將值轉換為int型別
?float(value)
將值轉換為float型別
?string(value)
將變數轉換成字串
?trim(value)
截取字串前面和后面的空白字符
2. 自定義過濾器
除了使用Jinja2模板內置的過濾器,還可以自定義過濾器
如下示例:
運行測驗:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def cut():
context = {
'word': 'Hello World'
}
return render_template('cut.html', **context)
@app.template_filter('replace1')
def replace1(value):
return value.replace(' ', '---')
if __name__ == '__main__':
app.run(debug=True)
模板cut.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask模板</title>
</head>
<body>
<h2>{{word}}</h2>
<h2>{{word|replace1}}</h2>
</body>
</html>
網頁顯示:

由上述得:空格被替換為- - -
自定義過濾器相當于定義函式,同時需要用裝飾器@app.template_filter(‘replace1’)來裝飾,傳入的引數即為過濾器名
?自定義有以下功能的過濾器:
發布一篇博客,當發布時間,小于1分鐘,顯示剛剛;
大于1分鐘小于1小時,顯示XX分鐘前;
大于1小時小于24小時,顯示XX小時前;
…
運行測驗:
from datetime import datetime
from flask import Flask, render_template
app = Flask(__name__)
app.config['TEMPLATE_AUTO_RELOAD'] = True
@app.route('/')
def index():
context = {
'release_time1': datetime(2020, 10, 20, 16, 30, 0),
'release_time2': datetime(2020, 10, 21, 13, 45, 0)
}
return render_template('cut.html', **context)
@app.template_filter('time_handler')
def handle_time(time):
if isinstance(time, datetime):
now = datetime.now()
time_delta = (now - time).total_seconds()
if time_delta < 60:
return '剛剛寫的博客'
elif (time_delta >= 60) and (time_delta < 60 * 60):
return '%d分鐘之前寫的博客' % (time_delta // 60)
elif (time_delta >= 60 * 60) and (time_delta < 60 * 60 * 24):
return '%d小時之前寫的博客' % (time_delta / 60 // 60)
else:
return time
if __name__ == '__main__':
app.run(debug=True)
模板cut.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask</title>
</head>
<body>
<h1>以下是博客發表時間:</h1>
<h2>文章發表時間:{{release_time1}}</h2>
<h2>文章發表時間:{{release_time1 | time_handler}}</h2>
<h2>文章發表時間:{{release_time2}}</h2>
<h2>文章發表時間:{{release_time2 | time_handler}}</h2>
</body>
</html>
網頁顯示:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/188099.html
標籤:其他
