9.註冊和登陸功能實現(2)—— 註冊與登陸的錯誤提示

在註冊和登陸功能實現(1)中,咱們已經獲取到了頁面POST過來的登陸或者註冊數據,接下來咱們須要與數據庫中的數據作驗證,驗證經過才能登陸或者註冊。咱們平時在登陸網站時,若是輸入的用戶名或者密碼錯誤,有的網站是在登陸框附近提示錯誤,也有的是跳轉到一個頁面提示出錯,並通過幾秒倒計時再返回原來的頁面。
咱們在後續作搜索功能的時候,用頁面跳轉來處理未找到結果的情形,這裏就經過使用Flaskflash功能,直接在當前頁面顯示錯誤提示。簡單來講,步驟就是在視圖函數中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')

在視圖函數中flashmessage,接下來咱們須要在html中顯示它,咱們再去修改base.html(這樣對register.htmllogin.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

clipboard.png
只是不太美觀,咱們再用css調整一下,藉助Boostrap中的警告框樣式,最終結果以下:session

clipboard.png

登陸也是同理,就不演示啦。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

clipboard.png


實際上更簡單的方法是,咱們直接對傳入的{{ message }}進行判斷,若是帶有'成功'字符串,就顯示藍色,不然就顯示紅色。上文主要是爲了說明@app.context_processor這個裝飾器,以及sessiong對象的區別。

相關文章
相關標籤/搜索