使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(三)——使用Flask-Login庫實現登錄功能


使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(一)——創建應用

使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(二)——使用藍圖功能進行模塊化

使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(三)——使用Flask-Login庫實現登錄功能

使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(四)——對 run.py 的調整

使用 Flask 框架寫用戶登錄功能的Demo時碰到的各種坑(五)——實現注冊功能

 

本次示例的源碼下載:點擊下載

Flask-Login 庫的中文文檔:點擊進入

Flask-Login 庫的新版英文文檔:點擊進入

使用 WTForms 進行表單驗證:點擊進入

 

一、導入並初始化 Flask-Login 庫

在項目根目錄下的/demo/__init__.py 文件的頭部,import 進 flask_login 庫

from flask_login import LoginManager

在 create_app 函數的前面加入初始化操作:

"""
初始化登錄管理器
"""
login_manager = LoginManager()

"""
這里的參數格式是:藍圖名稱.函數名
這里是指定了當用戶未登錄的時候,進入需要登錄才能進入的頁面時,會自動跳轉到的頁面。
"""
login_manager.login_view = "user.login"

在 create_app 函數中的 app = Flask(__name__) 下面加入:

login_manager.init_app(app)

完整的代碼是:

二、實現登錄模塊

 1.增加 MD5 加密公共函數

在該路徑下創建文件並編寫以下代碼:

/demo/common/encrypt.py

def md5(text):
    import hashlib
    m = hashlib.md5()
    t = text.encode(encoding="utf-8")
    m.update(t)
    return m.hexdigest()

2.創建用戶模塊

①創建以下目錄

/demo/modules/users

/demo/modules/users/forms

/demo/modules/users/models

/demo/modules/users/templates

②創建 /demo/modules/users/views.py

3.使用 Flask-WTF 庫來驗證提交的表單,點擊查看文檔

 在 forms 目錄下 創建 users.py 文件,做登錄表單驗證

/demo/modules/users/forms/users.py

# config=utf-8
from flask_wtf import Form
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length, Email


class LoginForm(Form):
    accountNumber = StringField('accountNumber', validators=[DataRequired('賬號不可以是空的'),
                                                             Length(-1, 200, '賬號的字符數不可以超過 200 個'),
                                                             Email('賬號只能是郵箱')])
    password = PasswordField('password', validators=[DataRequired('密碼不可以是空的'),
                                                     Length(6, 20, '密碼的字符數只能在 6 - 20 個之間')])

 

 

4.創建操作數據庫類

/demo/modules/users/models/users.py

# config=utf-8
from flask_login import UserMixin
from demo.common import db


class User(db.Model, UserMixin):
    """
    用戶實體信息
    Attributes:
        id:用戶編號。
        accountNumber:賬號。
        password:密碼。
        name:用戶昵稱。
    """
    id = db.Column(db.Integer, primary_key=True)
    accountNumber = db.Column(db.String(200), unique=True)
    password = db.Column(db.String(50), unique=True)
    name = db.Column(db.String(20), unique=True)

    __tablename__ = 'py_user'

    def __init__(self, user_id=None, account_number=None, password=None, name="anonymous"):
        """
        初始化用戶信息。
        Args:
            user_id (int): 用戶編號
            account_number(string):賬號
            password(string):密碼
            name (string):昵稱
        """
        self.id = user_id
        self.accountNumber = account_number
        self.password = password
        self.name = name

db.Model 類是數據庫操作類,實現了數據庫的功能。

UserMixin 是 flask-login 庫提供的一個用戶的基類,定義了 flask-login 的登錄用戶必需使用到的屬性和方法等。

5.在 views.py 中實現具體的登錄功能。

/demo/modules/users/views.py 的完整代碼

# config=utf-8
from flask import Blueprint, request, redirect, url_for
from flask import render_template
from flask_login import login_user, logout_user
from demo import login_manager
from demo.common.encrypt import md5
from demo.modules.users.models.users import User
from demo.modules.users.forms.users import LoginForm

userRoute = Blueprint('user', __name__, url_prefix='/user', template_folder='templates', static_folder='static')


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))


@userRoute.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()

    if request.method == 'POST':
        if not form.validate_on_submit():
            return render_template('login.html', form=form)

        user = User.query.filter(User.accountNumber == form.accountNumber.data,
                                 User.password == md5(form.password.data)).first()

        if user:
            login_user(user)
            return redirect("/")

    return render_template('login.html', form=form)


@userRoute.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('.login'))

其中,要以 @login_manager.user_loader 來描述一個函數,表示 flask-login 庫在獲取當前已登錄的用戶信息時,會該用該函數來獲取:

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

 

 

6.注冊用戶模塊,在 /run.py 文件里增加:

from demo.modules.home.views import homeRoute
from demo.modules.users.views import userRoute

DEFAULT_MODULES = [homeRoute,
                   userRoute]

/run.py 完整代碼:

# config=utf-8
from demo import create_app
from demo.modules.home.views import homeRoute
from demo.modules.users.views import userRoute

DEFAULT_MODULES = [homeRoute,
                   userRoute]

app = create_app('config.py')

for module in DEFAULT_MODULES:
    app.register_blueprint(module)


@app.before_request
def before_request():
    """
    這里是全局的方法,在請求開始之前調用。
    其中 flask 有個全局的變量 g,它是和 session 一樣的用途,可以使用它來保存當前用戶的數據
    Returns:

    """
    pass


if __name__ == '__main__':
    app.run()

 

7.創建模板頁面

①創建以下目錄:

/demo/static

/demo/static/js

/demo/static/css

/demo/static/img

分別用於保存 JS、CSS 和圖片。

頁面調用的靜態文件的目錄是應用目錄下的 static 目錄,如果將這些文件放到其它目錄中 ,則無法在頁面中引用。

 ②下載 jquery 並保存在/static/js/jquery/目錄下

/static/js/jquery/jquery-2.2.0.min.js

③在 /demo/templates/base.html 中引入 jquery:

<!DOCTYPE html>
<html lang="cn">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
    <script src="/static/js/jquery/jquery-2.2.0.min.js"></script>
    {% block head %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>

④在 /demo/modules/users/templates 目錄創建 login.html 頁面:

{% extends "base.html" %}
{% block title %}python flask user page{% endblock %}
{% block head %}
    <style type="text/css"></style>
{% endblock %}
{% block content %}
    <form action="{{ url_for('user.login') }}" method="post">
        {% if form.errors %}
            <ul>
                {% for name, errors in form.errors.items() %}
                    {% for error in errors %}
                        <li>{{ error }}</li>
                    {% endfor %}
                {% endfor %}
            </ul>
        {% endif %}
        賬號:{{ form.accountNumber(size=20) }}<label>{{ form.accountNumber.errors[0] }}</label><br/>
        密碼:<input name="password" type="password"/><br/>
        {{ form.hidden_tag() }}
        <button type="submit">登錄</button>
    </form>
    <a href="/">返回</a>
{% endblock %}

其中這段表示遍歷輸出所有表單錯誤信息。

        {% if form.errors %}
            <ul>
                {% for name, errors in form.errors.items() %}
                    {% for error in errors %}
                        <li>{{ error }}</li>
                    {% endfor %}
                {% endfor %}
            </ul>
        {% endif %}

 

完成了,這幾章只是對在 Flask 使用中的一種補充和記錄,具體還是查文檔。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM