原文:http://www.catonlinepy.tech/
聲明:原創不易,未經許可,不得轉載css
經過第三天的學習內容,你將對錶單的使用有所認識。知道如何經過使用插件來處理應用中的表單,之後在開發過程當中也可以更熟練地使用Flask_WTF插件實現表單相關的處理邏輯。今天學習內容涉及到的代碼都會託管到github上,在學習本課內容時,必定要本身嘗試手敲代碼,遇到問題再到貓姐的github上去查看代碼,若是實在不知道如何去解決問題,能夠在日誌下面留言說明具體狀況。html
WTForms做爲處理Web表單的插件,是一款支持多個web框架的form組件。Flask-WTF插件對其類WTForms進行封裝後以便它可以與Flask完美的結合。在第三天的內容中,咱們將引入第一個Flask插件,後續也會對其它的插件進行引入。要知道,插件用得好,可使web的開發的過程快到飛起。前端
你們需知道,全部Flask插件都是屬於Python的三方包,所以均可以使用pip來進行安裝。照舊,咱們先進入miao_venv的虛擬環境目錄中,將虛擬環境進行激活,而後安裝Flask_WTF插件。安裝步驟以下:python
# 進入到虛擬環境目錄,激活虛擬環境 maojie@Thinkpad:~/flask-plan/$ source miao_venv/bin/activate # 再安裝Flask_WTF插件 (miao_venv) maojie@Thinkpad:~/flask-plan$ pip install Flask_WTF
今天的代碼組織結構以下:git
# 使用tree命令查看 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3$ tree . ├── form_demo │ ├── __init__.py │ ├── routes.py │ └── templates │ ├── form.html │ └── layout.html └── run.py
如今貓姐來建立今天的課程目錄,步驟以下:github
# 在flask-course-primary目錄下建立第三天的課程day3目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ mkdir day3 # 進入day3目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ cd day3 # 新建form_demo (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3$ mkdir form_demo # 進入到form_demo包 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3$ cd form_demo/ # 在form_demo包中新建__init__.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo$ touch __init__.py # 在form_demo新建routes.py路由文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo$ touch routes.py # 在day3目錄下新建run.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/$ touch run.py
上面將課程目錄建立好後,如今咱們開始表單的建立。在建立表單以前,貓姐先在__init__.py文件中對Flask_WTF進行配置,以下所示:web
# __init__.py文件中的內容 from flask import Flask # 從flask包中導入Flask類 app = Flask(__name__) # 經過Flask類建立一個app實例 app.config['SECRET_KEY'] = 'miaojie is great!' # 對Flask_WTF進行配置 from form_demo import routes # 解釋:對Flask_WTF進行配置主要是爲了防跨站請求僞造保護。由於在默認的狀況下,Flask_WTF可以保護全部的表單免受跨站請求僞造的攻擊(Cross-Site Request Forgery,CSRF),可是在特殊狀況下,一些惡意網站會把請求發送到被攻擊者已登陸的其它網站時就會發生CSRF攻擊。爲了實現CSRF的保護,Flask_WTF須要程序設置一個密鑰,而後它使用密鑰去生成一個加密令牌,再用令牌驗證請求中的表單數據的真僞。(這裏不懂也沒事,問題不大!)
下面開始一個簡單的Web 表單,貓姐開始利用Flask_WTF插件來建立Web表單,表單內容寫入到routes.py文件中,以下所示:數據庫
# routes.py文件中的內容 # 從flask_wtf庫中導入FlaskForm類 from flask_wtf import FlaskForm # 從wtforms中導入表單的字段對象類 from wtforms import StringField, PasswordField, BooleanField, SubmitField # 從wtforms.validators字段驗證器中導入DataRequired驗證函數 from wtforms.validators import DataRequired # LoginForm類函數,繼承自FlaskForm基類 class LoginForm(FlaskForm): # 表單包括用戶名,密碼和是否記住密碼及一個提交按鈕 username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()]) remember = BooleanField('Remember Me') submit = SubmitField('Sign In')
因爲只須要用戶輸入用戶名、密碼、記住登陸狀態以及提交按鈕,因此表示web表單的LoginForm僅包含了用戶名,密碼和是否記住密碼可選框以及提交按鈕這4個字段。其中,StringField類表示屬性爲type="text"的<input>元素;PasswordField類表示屬性爲type="password"的<input>元素;BooleanField表示爲true或false的可選框;SubmiteField表示屬性爲type="submit"的<input>元素,而Username,Password,Remember Me表示標籤名稱(label)。在字段類中的可選參數—validators—是一個list變量,能夠向類填充不一樣的校驗函數,它在用戶提交表單按鈕前驗證數據,這裏僅僅只驗證了字段輸入是否爲空。flask
接下來是表單在前端的渲染,將表單內容添加到模板中,讓瀏覽器進行渲染,用戶在網頁中就能夠看到表單了。下面開始進行模板的建立,以下所示:瀏覽器
# 在form_demo中建立templates目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo$ mkdir templates # 進入templates目錄 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo/$ cd templates # 建立基模板layout.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo/templates$ touch layout.html # 建立子模板form.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day3/form_demo/templates$ touch form.html
在第二課中貓姐已經講到了模板的繼承,在今天的課程中仍是用到繼承這個概念。在templates/layout.html中寫入以下代碼:
<!-- layou.html文件中的內容 --> <html> <head> {% if title %} <title>{{ title }} - 表單的使用-喵星在線</title> {% else %} <title>表單的使用-喵星在線</title> {% endif %} </head> <body> {% block content %} {% endblock %} </body> </html>
而後子模板繼承基模板,在templates/form.html中寫入以下代碼:
<!-- form.html文件中的內容 --> {% extends "layout.html" %} {% block content %} <h1>Sign In</h1> <form action="" method="post"> # 防跨站僞造請求 {{html_form.hidden_tag() }} <div> # 顯示Username標籤名稱 {{ html_form.username.label }} # Username輸入框 {{ html_form.username() }} </div> <div> # 顯示Password標籤名稱 {{ html_form.password.label }} # 密碼輸入框 {{ html_form.password() }} </div> <div> # 顯示Remember Me標稱名稱 {{ html_form.remember.label }} # 是否勾選記住密碼框 {{ html_form.remember() }} </div> <div> # 顯示提交按鈕 {{ html_form.submit() }} </div> </form> {% endblock content %}
經過<form></form>建立表單,它的action屬性告訴瀏覽器用戶在提交表單時將發送請求的URL,當action爲空時,表示請求的是當前的URL頁面,裏面也能夠輸入用戶想請求的URL。method屬性指定了表單提交給服務器的HTTP請求方法,由於裏面要傳送數據,因此請求方法爲post。
上面已經完成了前臺的form表的顯示(渲染)工做,這時就須要在視圖函數中將表明表單的類傳遞到前端模板文件中,這裏是form.html文件。下面在routes.py中編寫視圖函數:
# routes.py文件中的內容 # 從flask庫中導入render_template from flask import render_template # 表單內容 # 從flask_wtf庫中導入FlaskForm類 from flask_wtf import FlaskForm # 從wtforms中導入表單的字段對象類 from wtforms import StringField, PasswordField, BooleanField, SubmitField # 從wtforms.validators字段驗證器中導入DataRequired驗證函數 from wtforms.validators import DataRequired # 編寫LoginForm類函數,繼承FlaskForm基類 class LoginForm(FlaskForm): # 表單包括用戶名,密碼和是否記住密碼及一個提交按鈕 username = StringField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()]) remember = BooleanField('Remember Me') submit = SubmitField('Sign In') # 添加視圖函數渲染表單內容 @app.route('/login') def login(): # 對類LoginForm的實例 form = LoginForm() # 將視圖函數中的變量form傳到模板form.html文件中去 return render_template('form.html', title='第三天', html_form=form)
如今,全部代碼已編寫完成,經過pythonn run.py(run.py文件的內容與次日教程的內容相同))將web程序拉起,開始驗證結果,在瀏覽器中輸入http://127.0.0.1:5000/login,效果圖以下所示:
在上面的結果中,貓姐只是完成了表單前臺的渲染,可是還不能在表單中發送數據,下面貓姐將介紹,後臺接收到用戶發送form表單內容後,如何進行處理。
上面的例子中,在表單中輸入用戶名和密碼後,點擊提交按鈕,發現瀏覽器沒有任何反應,後臺程序並不能處理post請求,因此如今須要修改後臺程序routes.py,讓其可以處理post請求,更改代碼以下:
# routes.py文件中對視圖函數進行修改,處理post語法 # 添加視圖函數渲染表單內容 # 在裝飾器函數中添加http請求方法 @app.route('/login',methods=['GET','POST']) def login(): # LoginForm的實例化 form = LoginForm() # 添加處理post請求的代碼 if from.validate_on_subimit(): # 調用flash函數,在flash消息中提示用戶及記住remember狀態成功 flash('登陸用戶 {},記住remember狀態{}成功'.format(form.username.data,form.remember.data), 'success') # 將視圖函數中的變量form傳到模板form.html文件中去 return render_template('form.html', title='第三天', html_form=form) # 解釋:flash消息中,form.username.data是獲取表單中的用戶名,form.remember.data是獲取表單中的記住密碼的狀態(它的狀態是true或是false)
當在瀏覽器中點擊提交按鈕後,瀏覽器會發送post請求,就會執行上面的if條件語句,並渲染flash消息到瀏覽器中。瀏覽器默認發送的是get請求,因此當沒有點擊提交按鈕時,就會跳過if語句,直接執行return語句。
可是當你調用flash函數後,在瀏覽器中並無渲染flash消息,這是由於須要將消息渲染到基模板中,才能在全部的子模板中顯示出來。如今來更新layout.html代碼:
<!-- layout.html文件中的內容 --> <html> <head> {% if title %} <title>{{ title }} - 表單的使用-喵星在線</title> {% else %} <title>表單的使用-喵星在線</title> {% endif %} </head> <body> <!-- 渲染flash消息 --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}"> {{ message }} </div> {% endfor %} {% endif %} {% endwith %} {% block content %} {% endblock %} </body> </html>
在瀏覽器中打開網址 http://localhost:5000/,查看結果:
在上圖中就能夠將flash的消息渲染出來了,可是,這個flash消息並不會消失,而且顯示效果也不美觀。這是由於咱們沒有給它添加任何css樣式,這個問題在後面的教程中也會講到。
學習完今天的教程,咱們掌握了以下技能:
第四天的內容,咱們將會帶領你們一塊兒瞭解使用flask的插件來建立數據庫,怎麼對數據庫進行操做,第三天的內容就到這裏,喜歡的同窗們能夠在下面點贊留言,或是訪問個人博客地址:http://www.catonlinepy.tech/ 加入咱們的QQ羣進一步交流學習!
今天的課程就到這裏,你們能夠到github上去獲取以上教程中的全部代碼:https://github.com/miaojie19/...
具體下載代碼的命令以下:
# 使用git命令下載flask-course-primary倉庫全部的代碼 git clone https://github.com/miaojie19/flask-course-primary.git # 下載完成後,進入day3目錄下面,便可看到今天的代碼 cd flask-course-primary cd day3