美文网首页
day57-flask中连接数据库,登陆及session使用

day57-flask中连接数据库,登陆及session使用

作者: barriers | 来源:发表于2019-01-22 21:41 被阅读0次

    1普通登陆

    1.1服务器上安装redis

    先查看服务器上是否已有redis:redis-cli或者redis-server

    yum install redis # 安装
    redis-server &  # 启动服务端并置于后台运行
    redis-cli  # 启动客户端
    

    flushall 清空redis数据库中所有的键值对

    1.2登陆

    session['user_id'] = 1 给session设置一个键为user_id,值为1的键值对

    @blue.route('/login/', methods=['GET', 'POST'])
    def login():
        if request.method == 'GET':
            return render_template('login.html')
    
        if request.method == 'POST':
            1.获取数据
            username = request.form.get('username')
            password = request.form.get('password')
            2.session的使用
            if username == 'coco' and password == '123':
                 模拟登陆,设置一个键值对
                session['user_id'] = 1
                return redirect(url_for('first.my_index'))
            return render_template('login.html')
    

    1.3初始化相关数据及设置

    使用flask自带的session进行存储数据等操作时
    存储数据:将session中存储的键值对内容存储在cookie中
    存储方式:在manage.py文件中设置加密复杂程度secret_key参数,越复杂越好

    app.secret_key = 'adfafdeqwrqer777qre'
    

    使用方式:from flask import session
    session['key']=value
    使用flask-session库进行session操作时
    安装三方库:pip install flask-session
    配置flask_session库,存储数据在redis中:

    flask对象.config['SESSION_TYPE']='redis'
    flask对象.config['SESSION_REDIS']=redis.Redis(host,port,password)
    

    初始化session对象:
    from flask_session import Session
    初始化时有两种方案,以第二种较为常用

    Session(app) # 一种方式
    
    se = Session()
    se.init_app(app) # 二种方式
    

    第一次访问任何一个路由地址时,在客户端,将在cookie中存储一个键值对,键为session,值为唯一的uuid类型的参数;第一次访问的同时,在服务端的指定的redis中,也将存储cookie中的uuid值
    如果用户登陆成功,则可以向redis中存储的uuid参数中保存信息

    2模型映射

    安装数据库的三方库

    pip install flask-sqlalchemy
    

    2.1创建模型

    from flask_login import UserMixin
    from flask_sqlalchemy import SQLAlchemy    
     生成连接数据库的对象
    db = SQLAlchemy()
    class User(db.Model, UserMixin):
         定义自增的主键
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
         定义长度为10的name字段,类型为字符串,唯一且不能为空
        name = db.Column(db.String(10), unique=True, nullable=False)
        定义密码password字段
        password = db.Column(db.String(249), nullable=False)
        定义表的名字
        __tablename__ = 'flask_user'
    

    db = SQLAlchemy():生成连接数据库的对象

    2.2模型迁移

    模型可以用migrate库实现迁移,但需要先安装,所以本处通过访问路由的形式来实现迁移。但这种迁移只能使用一次(模型对应的表名不存在于数据库中时,才可使用)

    @blue.route('/create_db/')
    def create_db():
        只能用一次(模型对应的表名不存在于数据库中时,才可使用)
        db.create_all()
        return '创建表成功'
    

    当将db.create_all()换成db.drop_all()时,即是删除表格

    2.3初始化数据库连接信息

    先配置数据库

    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/flask8'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    

    初始化数据库信息

    db.init_app(app)
    

    3装饰器

    装饰器三要素:
    1.外层函数嵌套内层函数
    2.外层函数返回内层函数
    3.内层函数调用外层函数的参数
    装饰器中外层函数下必须写@wraps(参数)。不加@wraps(func),被装饰的f函数将会变成is_login函数,加了后才能依旧保持是f函数

    from functools import wraps
    def is_login(func):
        @wraps(func)
        def check():
            return func()
        return check
    @is_login
    def f():
        return '123'
    print(f)
    

    4使用数据库模型进行注册

    @blue.route('/my_register/', methods=['GET', 'POST'])
    def my_register():
        if request.method == 'GET':
            return render_template('register.html')
        if request.method == 'POST':
             获取参数
            usermame = request.form.get('username')
            pwd = request.form.get('pwd')
            cpwd = request.form.get('cpwd')
            验证
            if usermame and pwd and cpwd:
                 用户名是否已注册
                user = User.query.filter(User.name == usermame).first()
                if user:
                    return render_template('register.html', error_name='用户名已注册')
                if pwd != cpwd:
                    return render_template('register.html', error_name='密码和确认密码不一致')
                u = User()
                u.name = usermame
                u.password = generate_password_hash(pwd)
                 创建并提交
                db.session.add(u)
                db.session.commit()
                return redirect(url_for('first.my_login'))
            else:
                 传递参数有空的情况
                return render_template('register.html')
    

    user = User.query.filter(User.name == usermame).first():数据库中查询是否有usermame这个名字的对象
    flask中创建模型对象并赋值
    u = User()
    u.name = usermame
    u.password = generate_password_hash(pwd)
    创建并提交
    db.session.add(u)
    db.session.commit()
    u.password = generate_password_hash(pwd):对输入的密码进行加密存储

    5使用flask-login进行登陆

    5.1登陆

    login_manage = LoginManager()
    
    @blue.route('/my_login/', methods=['GET', 'POST'])
    def my_login():
        if request.method == 'GET':
            return render_template('login.html')
        if request.method == 'POST':
             获取登陆的参数
            username = request.form.get('username')
            password = request.form.get('password')
            获取登陆的用户对象
            user = User.query.filter(User.name == username).first()
            if user:
                校验密码是否一致
                if check_password_hash(user.password, password):
                     使用flask-login实现登陆操作
                     向session中存键值对,键为user_id,值为id值
                    login_user(user)
                    return redirect(url_for('first.my_index'))
                else:
                    return render_template('login.html', error_pwd='密码错误')
            else:
                return render_template('login.html', error_name='用户没有注册,请去注册')
    

    check_password_hash(user.password, password):对传入的密码进行比对
    login_user(user):使用flask-login实现登陆操作,向session中存键值对,键为user_id,值为id值;在写了这句后,在其下面还必须写一个函数

    @login_manage.user_loader
    def load_user(user_id):
        定义被login_manage装饰的回调函数
        返回的是当前登陆系统的用户对象
        return User.query.filter(User.id == user_id).first()
    

    上面代码是将传入的user_id转换成相应的用户并存储,返回的是当前登陆系统的用户对象;这样在文件中就能直接拿到用户信息。

    5.2使用装饰器对登陆状态进行校验

    from flask import session, redirect, url_for
    from functools import wraps        
    def is_login(func):
        @wraps(func)
        def check_status(*args, **kwargs):
            try:
                session['user_id']
                return func(*args, **kwargs)
            except Exception as e:
                return redirect(url_for('first.login'))
        return check_status
    

    使用装饰器进行校验

    @blue.route('/my_index/', methods=['GET', 'POST', 'PATCH'])
    @is_login
    def my_index():
        if request.method == 'GET':
            return render_template('index.html')
        if request.method == 'POST':
            return render_template('login.html')
    

    5.3初始化flask-login对象

    login_manage.init_app(app)
    

    login_manage,为视图页面的flask-login对象( login_manage = LoginManager())

    5.4页面解析当前登陆对象

    当在视图页面定义了load_user函数后,可以直接在html页面对当前登陆用户的信息进行解析

    <body>
      <p>这是个什么鬼玩意儿</p>
      <p>登陆才能访问</p>
      {{ current_user.name }}
    </body>
    

    5.5一些常用的方法

    注册 flask-login
    加密:generate_password_hash()
    解密:check_password_hash()
    安装:pip install flask-login
    初始化:lm = LoginManage() lm.init_app(flask对象)
    登陆用户:login_user(登陆系统用户对象)
    重点:用户的模型中必须继承UserMixin,或者自定义相关的属性与方法
    注销用户:logout_user()
    登陆校验:login_required
    在模板中可使用{{ current_user.name }}渲染登陆系统的用户名信息
    必须定义回调user_loader,用于返回登陆系统的用户对象

    相关文章

      网友评论

          本文标题:day57-flask中连接数据库,登陆及session使用

          本文链接:https://www.haomeiwen.com/subject/enurjqtx.html