小白學Flask第九天| 看看模板的那些事(一)
- 2019 年 10 月 5 日
- 筆記
1. 模板
2. 過濾器
3. 引入表單的拓展
4. 使用表單接受並檢驗參數
模板
在Flask當中的模板被稱為Jinja2模板,那麼我們怎麼去使用模板呢?大家可以看到下面兩塊程式碼:
# -*- coding: utf-8 -*- from flask import Flask, render_template app = Flask(__name__) @app.route("/index") def index(): return render_template("index.html", name="kuls", age=18) if __name__ == '__main__': app.run(debug=True)
在templates當中創建的index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>name = {{name}}</p> <p>age = {{age}}</p> </body> </html>
我們運行程式碼:

從上面可以知道在Flask當中模板變數為 {{變數名}} ,模板渲染使用render_template()函數。
在程式碼中還能發現我們在render_template()是通過鍵值對的形式來給模板變數賦值,那麼我們還能通過其他形式來進行傳參嗎?當然是可以的,我們可以通過字典的形式來進行傳參。
# -*- coding: utf-8 -*- from flask import Flask, render_template app = Flask(__name__) @app.route("/index") def index(): data = { "name":"kuls", "age": 18 } return render_template("index.html", **data) if __name__ == '__main__': app.run(debug=True)
那還有什麼騷操作沒?看下面:
# -*- coding: utf-8 -*- from flask import Flask, render_template app = Flask(__name__) @app.route("/index") def index(): data = { "name":"kuls", "age": 18, "dict":{"city": "cs"}, "list":[0, 1, 2, 3], "int":1 } return render_template("index.html", **data) if __name__ == '__main__': app.run(debug=True)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>name = {{name}}</p> <p>age = {{age}}</p> <p>dict city= {{ dict["city"] }}</p> <p>dict city= {{ dict.city }}</p> <p>list : {{ list }}</p> <p>list[int]: {{ list[int] }}</p> <p>list[1]+list[2]: {{ list[1]+list[2] }}</p> </body> </html>
運行一下:

可以看到我們可以在模板上進行運算以及對列表或者字典取值。
過濾器
字元串過濾器:
safe:禁用轉義;
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把變數值的首字母轉成大寫,其餘字母轉小寫;
<p>{{ 'hello' | capitalize }}</p>
lower:把值轉成小寫;
<p>{{ 'HELLO' | lower }}</p>
upper:把值轉成大寫;
<p>{{ 'hello' | upper }}</p>
title:把值中的每個單詞的首字母都轉成大寫;
<p>{{ 'hello' | title }}</p>
trim:把值的首尾空格去掉;
<p>{{ ' hello world ' | trim }}</p>
reverse:字元串反轉;
<p>{{ 'olleh' | reverse }}</p>
format:格式化輸出;
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML標籤都刪掉;
<p>{{ '<em>hello</em>' | striptags }}</p>
支援鏈式使用過濾器:
<p>{{ 「 hello world 「 | trim | upper }}</p>
列表過濾器:
first:取第一個元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
last:取最後一個元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
length:獲取列表長度
<p>{{ [1,2,3,4,5,6] | length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
自定義過濾器:
方式一:
通過add_template_filter (過濾器函數, 模板中使用的過濾器名字)
def filter_double_sort(ls): return ls[::2] app.add_template_filter(filter_double_sort,'double_2')
方式二:
通過裝飾器 app.template_filter (模板中使用的裝飾器名字)
@app.template_filter('db3') def filter_double_sort(ls): return ls[::-3]
引入表單的拓展
使用Flask-WTF表單擴展,可以幫助進行CSRF驗證,幫助我們快速定義表單模板,而且可以幫助我們在視圖中驗證表的數據。
pip install Flask-WTF
我們來看一下,沒使用表單拓展的時候是怎麼去寫表單的:
#模板文件 <form method='post'> <input type="text" name="username" placeholder='Username'> <input type="password" name="password" placeholder='password'> <input type="submit"> </form>
from flask import Flask,render_template,request @app.route('/login',methods=['GET','POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] print username,password return 「success」 else: return render_template(「login.html」)
看著上面是不是有點苦逼,這麼英俊瀟洒的你怎麼能這麼狼狽的寫程式碼呢?
使用表單接受並檢驗參數
我們接著來看一下使用了Flask-WTF拓展之後:
模板頁:
<form method="post"> #設置csrf_token {{ form.csrf_token() }} {{ form.us.label }} <p>{{ form.us }}</p> {{ form.ps.label }} <p>{{ form.ps }}</p> {{ form.ps2.label }} <p>{{ form.ps2 }}</p> <p>{{ form.submit() }}</p> {% for x in get_flashed_messages() %} {{ x }} {% endfor %} </form>
視圖函數:
#coding=utf-8 from flask import Flask,render_template, redirect,url_for,session,request,flash #導入wtf擴展的表單類 from flask_wtf import FlaskForm #導入自定義表單需要的欄位 from wtforms import SubmitField,StringField,PasswordField #導入wtf擴展提供的表單驗證器 from wtforms.validators import DataRequired,EqualTo app = Flask(__name__) # 需要設置 SECRET_KEY 的配置參數 app.config['SECRET_KEY']='1' #創建自定義表單類,文本欄位、密碼欄位、提交按鈕 class Login(FlaskForm): us = StringField(label=u'用戶:',validators=[DataRequired()]) ps = PasswordField(label=u'密碼',validators=[DataRequired(),EqualTo('ps2','err')]) ps2 = PasswordField(label=u'確認密碼',validators=[DataRequired()]) submit = SubmitField(u'提交') #定義根路由視圖函數,生成表單對象,獲取表單數據,進行表單數據驗證 @app.route('/',methods=['GET','POST']) def index(): # 創建一個Login對象 form = Login() if form.validate_on_submit(): # 調用Login對象當中的屬性,並取其數值 name = form.us.data pswd = form.ps.data pswd2 = form.ps2.data print(name,pswd,pswd2) # 重定向至login的裝飾器 return redirect(url_for('login')) else: if request.method=='POST': flash(u'資訊有誤,請重新輸入!') return render_template('index.html',form=form) if __name__ == '__main__': app.run(debug=True)
這樣一寫感覺整個的逼格就提升了好幾個檔次。在表單拓展當中需要注意必須得設置SECRET_KEY的值,這個值隨便你設置為多少(在前面的session當中我們也提到過SECRET_KEY)
在上面的程式碼當中,我把需要注釋的地方全部都注釋了,大家可以仔細去閱讀一些注釋。由於篇幅有限,這裡不對Flask-WTF的一些具體用法做闡述。