標籤:http io os ar 使用 java for strong sp
重新導向(Redirects)和使用者Session
目前我們寫的這個hello.py有個易用性的問題。如果你輸入name並提交,之後再點重新整理按鈕,那麼瀏覽器可能彈出一個莫名其表的警示,要求你確認是否重新發送表單資料,其實你什麼都沒做。這是因為瀏覽器的重新整理操作實際上是重複最後一次發送的請求,這種情況下最後一次請求就是發送帶有表單資料的POST請求。顯然大家都不想要這種效果。
許多使用者不理解瀏覽器彈出的這個警示。因此,對web應用來說的一個最佳實務就是:永遠不要讓POST請求成為瀏覽器的最後一個請求。
這個實踐可以通過利用redirect
來響應POST請求來實現。重新導向是一種特殊的response,他的內容是一個URL而不是一個HTML的字串。瀏覽器收到這種響應後,會向這個URL發出一個GET請求,然後這個頁面就顯示出來了。這種情況下,因為發送了兩次requset,耗時稍長,但體驗上影響不大。現在,最後一個請求是GET了,如果重新整理也不會有什麼警示。這個技巧被稱為 Post/Redirect/Get 模式。
好吧,這裡其實又引發另一個問題。當應用處理POST請求,把表單資料儲存到視圖函數的name
變數裡,這個變數的值在函數退出後就沒了。現在POST的響應是個重新導向,那麼就需要把這個值儲存下來。
應用可以利用 * user session來儲存requset之間的資料,這個儲存是對每個串連的使用者私人的。這個user session是之前的requset上下文裡提到的(這還是個坑,沒填了*)。操作方式跟字典類似。
註:預設情況下,session都是儲存在client端的cookies裡,並且通過之前配置的SECRET_KEY
加密簽名過的。任何試圖篡改其內容的都會導致簽名失敗,最終使session失效
來看重新導向版本的index()
:
from flask import Flask, render_template, session, redirect, url_for@app.route(‘/‘, methods=[‘GET‘, ‘POST‘])def index(): form = NameForm() if form.validate_on_submit(): session[‘name‘] = form.name.data return redirect(url_for(‘index‘)) return render_template(‘index.html‘, form=form, name=session.get(‘name‘))
註:代碼 4b tag
之前用一個臨時變數name
來儲存的資料,現在修改為放在session
中,這樣就可以在requset之間儲存住資料。
現在函數在有資料情況下返回的就是重新導向響應,通過redirect()
方法來實現。這個方法的入參是要重新導向到的URL,這裡用的是url_for()
函數,這個函數之前在模板裡講過,自動根據輸入的視圖函數名產生URL。直接寫個redirect(‘/‘)
在這裡效果是一樣的,但是不推薦。
‘url_for()‘只接受一個參數,就是路由端點名稱,預設情況下一條路由的端點名就是視圖函數名,所以上面寫的就是index
。
現在的網頁工作就正常了。
資訊提示
有時候需要給使用者一些提示資訊,報錯警示之類的。比如使用者登陸時候填錯密碼,就有訊息提示使用者名稱或密碼錯誤。
Flask架構把這個功能作為核心功能內建。flash()
方法用來做這個事。
顯示訊息的例子:
from flask import Flask, render_template, session, redirect, url_for, flash@app.route(‘/‘, methods=[‘GET‘, ‘POST‘])def index(): form = NameForm() if form.validate_on_submit(): old_name = session.get(‘name‘) if old_name is not None and old_name != form.name.data: flash(‘Looks like you have changed your name!‘) session[‘name‘] = form.name.data form.name.data = ‘‘ return redirect(url_for(‘index‘)) return render_template(‘index.html‘,form = form, name = session.get(‘name‘))
還是hello.py,這裡我們增加了一個flash()
使用。當使用者兩次提交不同名字的時候,我們的響應裡,就多了一條提示訊息。
只在代碼裡調用flash()
當然不能把訊息顯示出來,模板也需要修改。這個修改最好放到基礎模板裡做,這樣所有子模板就都不需要改動了。在模板裡可以通過get_flashed_messages()
方法接收訊息的內容。
還是例子,基礎模板templates/base.html
:
{% block content %}<div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">×</button> {{ message }} </div> {% endfor %} {% block page_content %}{% endblock %}</div>{% endblock %}
註: 代碼 4c tag
上面用了模板引擎支援的迴圈結構,每次在代碼裡調用flash()
,在get_flashed_messages()
時就多一個記錄,且這個記錄在提取出來之後就不能在擷取了。渲染時利用了Bootstrap的alert CSS樣式。:
下節開始就是資料庫了。
FlaskWebDevelopment - 表單的處理2- 重新導向&使用者session&提示資訊