在註冊和登陸功能實現(1)中,咱們已經獲取到了頁面POST過來的登陸或者註冊數據,接下來咱們須要與數據庫中的數據作驗證,驗證經過才能登陸或者註冊。咱們平時在登陸網站時,若是輸入的用戶名或者密碼錯誤,有的網站是在登陸框附近提示錯誤,也有的是跳轉到一個頁面提示出錯,並通過幾秒倒計時再返回原來的頁面。
咱們在後續作搜索功能的時候,用頁面跳轉來處理未找到結果的情形,這裏就經過使用Flask
的flash
功能,直接在當前頁面顯示錯誤提示。簡單來講,步驟就是在視圖函數中flash
一個字符串,在html
模板中使用get_flashed_messages()
去獲取這個字符串,並顯示在網頁中。
首先,咱們先新建一個exts.py
,用於存放一些功能性的函數,在其中寫一個去驗證登陸和註冊信息的函數,以下:css
from models import Users def validate(username, password1, password2=None): user = Users.query.filter(Users.username == username).first() if password2: if user: return '用戶名已經存在' else: if len(username) < 4: return '用戶名長度至少4個字符' elif password1 != password2: return '兩次密碼不一致' elif len(password1) < 6: return '密碼長度至少6個字符' else: return '註冊成功' else: if user: if user.password == password1: return '登陸成功' else: return '密碼錯誤' else: return '用戶名不存在'
要使用flash
功能,還得設置一個名爲SECRET_KEY
的參數,用於加密數據,咱們在config.py
中寫進去,隨便取個值SECRET_KEY = "THIS-A-SECRET-KEY"
。而後在HarpQA.py
中,從flask
中導入flash
,從exts.py
中導入validate
,修改register
視圖函數,以下:html
from flask import Flask, render_template, request, flash from models import db from exts import validate import config app = Flask(__name__) app.config.from_object(config) db.init_app(app) ... @app.route('/register/', methods=['GET', 'POST']) def register(): if request.method == 'GET': return render_template('register.html') else: username = request.form.get('username') password1 = request.form.get('password1') password2 = request.form.get('password2') message = validate(username, password1, password2) flash(message) return render_template('register.html')
在視圖函數中flash
了message
,接下來咱們須要在html
中顯示它,咱們再去修改base.html
(這樣對register.html
和login.html
都能起做用),在body
區域尾部增長以下代碼(直接從Flask
官方文檔複製修改的):數據庫
... <nav><!-- 導航條內容 --> ... </nav> <div class="body-container"> {% block body_part %} {% endblock %} </div> <div class="flash-message"> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} </div> </body>
而後運行程序,訪問註冊頁,隨便輸入幾個試試,發現已經能用了:flask
只是不太美觀,咱們再用css調整一下,藉助Boostrap中的警告框樣式,最終結果以下:session
登陸也是同理,就不演示啦。app
2017年1月17日補充內容:
當咱們登陸或註冊出現問題,出現的警告框是如上圖紅色的,顯然咱們不但願登陸或者註冊成功的時候也是紅色的,咱們將提示成功的顏色設置爲藍色,而後傳入一個參數給模板,告訴模板如今是成功仍是失敗的狀況,而後在html
中增長if
,如今的html
代碼以下:函數
<div class="flash-message"> {% with messages = get_flashed_messages() %} {% if messages %} <ul> {% for message in messages %} {% if status == 'OK' %} <li><div class="alert alert-info" role="alert">{{ message }}</div></li> {% else %} <li><div class="alert alert-danger" role="alert">{{ message }}</div></li> {% endif %} {% endfor %} </ul> {% endif %} {% endwith %} </div>
那麼status
這個參數是怎麼傳遞給模板呢,咱們以前提到在render_templates
函數中傳入,如今咱們使用@app.context_processor
這個裝飾器,它實際上是上下文管理器,其裝飾的函數返回的內容對全部html
模板都起做用,用法以下:網站
@app.context_processor def my_context_processor(): status = session.get('status', '') return {'status': status}
將其放在HarpQA.py
中,它返回一個字典,在任意html
中使用{{ key }}
,就能獲得這個字典key
對應的value
。那麼session
是什麼?在如今這個case中,咱們簡單理解其爲一個保存數據的容器,在登陸和註冊的視圖函數中,驗證完帳號密碼以後,將驗證結果的信息存入session
,例如註冊函數修改以下:加密
@app.route('/register/', methods=['GET', 'POST']) def register(): if request.method == 'GET': return render_template('register.html') else: username = request.form.get('username') password1 = request.form.get('password1') password2 = request.form.get('password2') message = validate(username, password1, password2) flash(message) if message == '註冊成功': session['status'] = 'OK' return redirect(url_for('login')) else: session['status'] = 'BAD' return render_template('register.html')
若是註冊成功,就向session
中寫入status
,值爲'OK'
,反之則爲'BAD'
。這樣html
模板就能根據status
顯示不一樣的顏色了。flask
中還有個g
對象也可用於保存和共享數據,但g
對象是基於每個請求的,不能跨請求使用。咱們註冊成功以後,要跳轉到登陸頁,此時g
就沒法使用了,而session
是基於這一次http
鏈接的,不一樣請求都能使用。url
實際上更簡單的方法是,咱們直接對傳入的{{ message }}
進行判斷,若是帶有'成功'
字符串,就顯示藍色,不然就顯示紅色。上文主要是爲了說明@app.context_processor
這個裝飾器,以及session
和g
對象的區別。