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 使用中的一种补充和记录,具体还是查文档。

  • 相关阅读:
    Ios8代码关闭输入预测问题
    iOS10 拍照崩溃问题
    iOS 圆的放大动画效果
    12-指针
    11-数组、字符串
    09-函数
    iOS 动画
    iOS 传值 委托(delegate)和block 对比
    IOS Table中Cell的重用reuse机制分析
    IOS 网络请求
  • 原文地址:https://www.cnblogs.com/cjnmy36723/p/5212047.html
Copyright © 2011-2022 走看看