zoukankan      html  css  js  c++  java
  • 使用 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 使用中的一种补充和记录,具体还是查文档。

  • 相关阅读:
    PostgreSQL中的partition-wise join
    Partition-wise join
    外观模式 门面模式 Facade 结构型 设计模式(十三)
    桥接模式 桥梁模式 bridge 结构型 设计模式(十二)
    组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)
    创建型设计模式对比总结 设计模式(八)
    原型模式 prototype 创建型 设计模式(七)
    单例模式 创建型 设计模式(六)
    建造者模式 生成器模式 创建型 设计模式(五)
    抽象工厂模式 创建型 设计模式(四)
  • 原文地址:https://www.cnblogs.com/cjnmy36723/p/5212047.html
Copyright © 2011-2022 走看看