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

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,用于返回登陆系统的用户对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容