Flask钩子函数


什么叫钩子函数呢?其实就是一个特殊的装饰器,用于某些 业务场景的前置操作和后置操作。

Flask 钩子函数

什么是 钩子函数?

钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作。一段用以处理系统消息的程序。“钩子”就是在某个阶段给你一个做某些处理的机会。
钩子函数: 1、是个函数,在系统消息触发时被系统调用 2、不是用户自己触发的。

Flask 钩子函数

执行顺序

钩子函数执行顺序

钩子函数使用

可以直接用在app 上, 也可以用在蓝图上

钩子函数作用在蓝图上

import os

from flask import Blueprint, request, render_template, redirect, url_for, jsonify, Response, session, g
from sqlalchemy import or_, and_, not_
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename

from ext import db
from settings import Config
from .modle import User
import hashlib

user_bp = Blueprint('user', __name__)
# 需要鉴权的路径
required_login_list = ["/user/center", '/user/change']
# 允许上传的图片格式
allow_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp']


@user_bp.route("/")
def base():
    return render_template('base.html')


@user_bp.before_app_first_request
def first_request():
    print("首次进这个蓝图")


# 重点
@user_bp.before_app_request
def first():
    print("蓝图里,所有的路由执行之前都会执行这里,可以用做鉴权")
    if request.path in required_login_list:
        uid = session.get('uid')
        if not uid:
            print("鉴权失败")
            # 重定向前面要有return 代表返回结束,不然就没有作用了
            return redirect(url_for('user.login'))
        else:
            print("鉴权成功")
            user = User.query.get(uid)
            g.user = user


@user_bp.after_app_request
def after_request_test(response):
    # response.set_cookie('a', 'bbbb', max_age=19)
    print('如果没有未处理的异常抛出,在每次请求结束运行')
    return response


@user_bp.teardown_app_request
def teardown_request_test(response):
    print('在每次请求后运行, 即使有未处理的异常抛出也执行')
    return response


@user_bp.route('/user/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('user/register.html')
    else:
        username = request.form.get("username")
        password = request.form.get('password')
        # 进行md5 加密
        # password = hashlib.md5(password.encode('utf-8')).hexdigest()
        password = generate_password_hash(password)
        phone = request.form.get('phone')
        email = request.form.get('email')
        user = User()
        user.username = username
        user.password = password
        user.email = email
        user.phone = phone
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("user.base"))


# 用于做手机号码的唯一性校验,通过阿贾克斯方式
@user_bp.route('/user/check_phone')
def check_phone_exists():
    phone = request.args.get('phone')
    user = User.query.filter(User.phone == phone).all()
    print("--------------------")
    print(user)
    # code: 400 不能用    200 可以用
    if len(user) > 0:
        return jsonify(code=400, msg='此号码已被注册')
    else:
        # print("看看这里进来了没有")
        return jsonify(code=200, msg='此号码可用')

@user_bp.route('/user/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('user/login.html')
    else:
        phone_num = request.form.get('phone')
        pwd = (request.form.get('password'))
        # print("--------看看原始密码-------------" + request.form.get('password'))
        user = User.query.filter(and_(User.isDelete == 0, User.phone == phone_num)).first()
        if user:
            flag = check_password_hash(user.password, pwd)
            if flag:
                # 通过 cookie 来记录登陆信息
                # 使用重定向就不能传递参数回去
                # response = redirect(url_for('user.base'))
                #  这样也是错误的, 返回的是一个str 对象
                # response = render_template('base.html', user=user)
                response = Response(render_template('user/index.html', user=user))
                # response.set_cookie('uid', str(user.id), max_age=1800)
                # 通过 sessionId来记录登陆信息
                session['uid'] = user.id
                print("看看session id " + str(session['uid']))
                return response
            else:
                return render_template('user/login.html', msg='用户名或者密码错误')
        else:
            return render_template('user/login.html', msg='用户未注册')


@user_bp.route('/user/logout')
def logout():
    response = Response(render_template('user/login.html'))
    # response.delete_cookie('uid')
    del session['uid']
    print("删除了session id")
    return response


@user_bp.route('/user/center', methods=['GET', 'POST'])
def center():
    #  g 是全局变量
    return render_template('user/center.html', user=g.user)


运行效果

运行效果

应用场景

可以看出, 就是一个装饰器, 可以用来做登陆的鉴权, 异常发生后也可以进行处理。


文章作者: 陌上人如玉
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 陌上人如玉 !
  目录