• Flask框架【before_first_request和before_request详解、钩子函数、Flask_信号机制】(七)


    👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白
    📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发
    📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
    🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
    🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人

    🔥🔥🔥 python入门到实战专栏:从入门到实战 

    🔥🔥🔥 Python爬虫开发专栏:从入门到实战

    🔥🔥🔥 Python办公自动化专栏:从入门到实战

    🔥🔥🔥 Python数据分析专栏:从入门到实战

    🔥🔥🔥 Python前后端开发专栏:从入门到实战

    文章目录

    before_first_request和before_request详解

    钩子函数context_processor详解

    钩子函数errorhandler详解

    Flask_信号机制

    Flask信号使用场景_存储用户登录日志

    Flask_内置信号


    before_first_request和before_request详解

    before_first_request:处理项目的第一次请求之前执行。

    1. from flask import Flask,request
    2. app = Flask(__name__)
    3. @app.route('/')
    4. def hello_world():
    5.    print("hi")
    6.    return "hello world "
    7. @app.before_first_request
    8. def first_request():
    9.    print('hello world')
    10. if __name__ == '__main__':
    11.    app.run(debug=True)

    before_request:在每次请求之前执行。通常可以用这个装饰器来给视图函数增加一些变量。

    请求已经到达了Flask,但是还没有进入到具体的视图函数之前调用。


    一般这个就是在视图函数之前,我们可以把一些后面需要用到的数据先处理好,方便视图函数使用。

    1. from flask import Flask,g,session
    2. app = Flask(__name__)
    3. app.config['SECRET_KEY'] = 'skidhfikshighsd'
    4. @app.route('/login/')
    5. def login():
    6.    print('运行代码 222222222')
    7.    print('Hello!!!!')
    8.    session['uname'] = '吕布'
    9.    return f'Hello'
    10. @app.route('/home/')
    11. def home():
    12.    print('运行代码 3333333333')
    13.    if hasattr(g, 'uname'):
    14.        return f'用户已登录!用户名是:{g.uname}'
    15.    return '用户没有登录!'
    16. @app.before_request
    17. def before_request():
    18.    print('运行代码 111111111111')
    19.    uname = session.get('uname')
    20.    if uname:
    21.        g.uname = uname
    22.    print('这个是每次请求时,需要执行的逻辑!!!')
    23. # 需求: 判断用户是否登录,如果登录了,就返回用户的信息,如果没有登录就返回None
    24. if __name__ == '__main__':
    25.    app.run(debug = True)

    钩子函数context_processor详解

    context_processor:上下文处理器。使用这个钩子函数,必须返回一个字典。这个字典中的值在所有模版中都可以使用。

    使用场景
    这个钩子函数的功能是,如果一些在很多模版中都要用到的变量,那么就可以使用这个钩子函数来返回,而不用在每个视图函数中的 render_template 中去写,这样可以让代码更加简洁和好维护。

    1. from flask import
    2. Flask,request,session,current_app,url_for,g,
    3. render_template
    4. import os
    5. app = Flask(__name__)
    6. app.config['SECRET_KEY']=os.urandom(24)  #加盐 混淆原数据的作用
    7. @app.route('/')
    8. def hello_world():
    9.    print("hi")
    10.    session['uname']="sxt"
    11.    # return "hello world "
    12.    return  render_template("index.html")
    13. @app.route('/li')
    14. def mylist():
    15.    print("mylist")
    16.    # print("直接取出",g.user)
    17.    if hasattr(g,"user"):
    18.        print("条件取出", g.user)
    19.    # return "hello world "
    20.    return render_template('list.html')
    21. @app.before_request
    22. def before_request():
    23.    # print('在视图函数执行之前执行的钩子函数')
    24.    # 场景:若用户已经登录了,验证时把用户名放入session中,之后取出来,放入钩子函数,以后访问的视图函数中可直接取出来使用
    25.   uname = session.get('uname')
    26.   print(uname)
    27.   if uname:
    28.       g.user = uname
    29. @app.context_processor
    30. def context_processor():
    31.    if hasattr(g,'user'):
    32.        return {"current_user":g.user}
    33.    else:
    34.        return {}
    35. if __name__ == '__main__':
    36.    app.run(debug=True)

    钩子函数errorhandler详解

    errorhandler:
    在发生一些异常的时候,比如404错误,比如500错误, 那么如果想要优雅的处理这些错误,就可以使用 errorhandler 来出来。

    需要注意几点:
    1、在errorhandler装饰的钩子函数下,记得要返回相应的状态码。
    2、在errorhandler装饰的钩子函数中,必须要写一个参数,来接收错误的信息,如果没有参数,就会直接报错。

    3、使用 flask.abort 可以手动的抛出相应的错误,比如开发者在发现参数不正确的时候可以自己手动的抛出一个400错误。

    常见的500错误处理

    1. from flask import
    2. Flask,g,render_template,abort
    3. app =Flask(__name__)
    4. @app.route('/')
    5. def index():
    6.    print(g.uname)
    7.    return 'Hello!'
    8. @app.errorhandler(500)
    9. def server_error(error): # server_error()
    10. takes 0 positional arguments but 1 was given
    11.    return render_template('500.html'),500 #状态码虽然可以不写,但是推荐写上,这样可以告诉服务器是哪个错误
    12.    # return render_template('500.html')
    13. if __name__ =="__main__":
    14.    # app.run(debug=True)
    15.    app.run()

    常见的404错误处理

    1. from flask import
    2. Flask,g,render_template,abort
    3. app =Flask(__name__)
    4. @app.route('/')
    5. def index():
    6.    print(g.uname)
    7.    return 'Hello!'
    8. @app.errorhandler(404)
    9. def server_error(error):
    10.    return render_template('404.html'),404
    11. if __name__ =="__main__":
    12.    # app.run(debug=True)
    13.    app.run()

    Flask中的abort函数可以手动的抛出相应的错误(如400)

    1. from flask import
    2. Flask,g,render_template,abort
    3. app =Flask(__name__)
    4. @app.route('/')
    5. def index():
    6.    print(g.uname)
    7.    return 'Hello!'
    8. @app.errorhandler(404)
    9. def server_error(error):
    10.    return render_template('404.html'),404
    11. @app.route('/home/')
    12. def home():
    13.    abort(404)
    14. if __name__ =="__main__":
    15.    # app.run(debug=True)
    16.    app.run()

    Flask_信号机制

    信号机制

    大白话来说,类似于两方属于敌对关系时,某人在敌对方阵营进行交谈,一旦遇到特殊情况,某人便会发送信号,他的同伙接收(监听)到他发的信号后,同伙便会做出一系列的应对策略(进攻|撤
    退)。
     flask中的信号使用的是一个第三方插件,叫做blinker。通过piplist看一下,如果没有安装,通过以下命令即可安装blinker

    pip install blinker
    

    自定义信号步骤

    自定义信号可分为3步来完成。

    第一是创建一个信号,第二是监听一个信号,第三是发送一个信号。

    以下将对这三步进行讲解:

    创建信号:定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间。比如定义一
    个在访问了某个视图函数的时候的信号。示例代码如下:

    1. # Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题
    2. from blinker import Namespace
    3. mysignal = Namespace()
    4. signal1 = mysignal.signal('信号名称')

    监听信号:监听信号使用signal1对象的connect方法,在这个方法中需要传递一个函数,用来监听
    到这个信号后做该做的事情。示例代码如下:

    1. def func1(sender,uname):
    2.    print(sender)
    3.    print(uname)
    4. signal1.connect(func1)

    发送信号:发送信号使用signal1对象的send方法,这个方法可以传递一些其他参数过去。示例代码如下:

    1. signal1.send(uname='momo')

    代码演示

    1. from flask import Flask
    2. from blinker import Namespace
    3. app = Flask(__name__)
    4. #【1】信号机制   3步走
    5. # Namespace:命名空间
    6. #1.定义信号
    7. sSpace = Namespace()
    8. fire_signal = sSpace.signal('发送信号火箭')
    9. #2.监听信号
    10. def fire_play(sender):
    11.    print(sender)
    12.    print("start play")
    13. fire_signal.connect(fire_play)
    14. #3.发送一个信号
    15. fire_signal.send()
    16. if __name__ == '__main__':
    17.    app.run(debug=True)

    Flask信号使用场景_存储用户登录日志

    信号使用场景
     定义一个登录的信号,以后用户登录进来以后
     就发送一个登录信号,然后能够监听这个信号
     在监听到这个信号以后,就记录当前这个用户登录的信息
     用信号的方式,记录用户的登录信息即登录日志

    编写一个signals.py文件创建登录信号

    1. from blinker  import  Namespace
    2. from datetime import datetime
    3. from flask import request,g
    4. namespace = Namespace()
    5. #创建登录信号
    6. login_signal = namespace.signal('login')
    7. def login_log(sender):
    8.    # 用户名 登录时间 ip地址
    9.    now = datetime.now()
    10.    ip = request.remote_addr
    11.    log_data = "{uname}*{now}*{ip}".format(uname=g.uname, now=now, ip=ip)
    12.    with open('login_log.txt','a') as f:
    13.        f.write(log_data + "\n")
    14.        f.close()
    15. #监听信号
    16. login_signal.connect(login_log)

    使用信号存储用户登录日志

    1. from flask import Flask,request,g
    2. from signals import  login_signal
    3. app = Flask(__name__)
    4. @app.route('/login/')
    5. def login():
    6.    # 通过查询字符串的形式来传递uname这个参数
    7.    uname = request.args.get('uname')
    8.    if uname:
    9.        g.uname = uname
    10.        # 发送信号
    11.        login_signal.send()
    12.        return '登录成功!'
    13.    else:
    14.        return '请输入用户名!'
    15. if __name__ == '__main__':
    16.    app.run(debug=True)

    Flask_内置信号

    Flask内置了10个常用的信号

    1、 template_rendered:模版渲染完成后的信号。

    2、 before_render_template:模版渲染之前的信号。

    3、 request_started:请求开始之前,在到达视图函数之前发送信号。

    4、 request_finished:请求结束时,在响应发送给客户端之前发送信号。

    5、request_tearing_down:请求对象被销毁时发送的信号,即使在请求过程中发生异常也会发送信号。
    6、got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。一般可以监听这个信号,来记录网站异常信息。

    7、appcontext_tearing_down:应用上下文被销毁时发送的信号。

    8、appcontext_pushed:应用上下文被推入到栈上时发送的信号。

    9、appcontext_popped:应用上下文被推出栈时发送的信号。

    10、message_flashed:调用了Flask的 flash 方法时发送的信号。

    template_rendered的使用

    1. from flask import
    2. Flask,render_template,template_rendered
    3. app = Flask(__name__)
    4. @app.route('/')
    5. def index():
    6.    return 'Hello!!'
    7. @app.route('/home/')
    8. def home():
    9.    return render_template('home.html')
    10. def
    11. render_function(sender,template,context):
    12.    print(sender)
    13.    print(template)
    14.    print(context)
    15. template_rendered.connect(render_function)
    16. if __name__ =='__main__':
    17.    app.run(debug=True)

    got_request_exception的使用

    1. from flask import
    2. Flask,request,got_request_exception,render_template
    3. app = Flask(__name__)
    4. #内置信号
    5. #got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。
    6. # 一般可以监听这个信号,来记录网站异常信息。
    7. # def
    8. request_exception_log(sender,*args,**kwargs)
    9. : #掌握写参数技巧
    10. #     print(sender)
    11. #     print(args)
    12. #     print(kwargs)
    13. def request_exception_log(sender,exception):
    14.    print(sender)
    15.    print(exception) # division by zero
    16. got_request_exception.connect(request_exception_log)
    17. @app.route('/')
    18. def hello_world():
    19.    #制造bug
    20.    a = 1/0
    21.    return
    22. render_template("index.html",data="momo")
    23. if __name__ == '__main__':
    24.    app.run(debug=True)

  • 相关阅读:
    RabbitMQ 消息应答与发布
    fatal:Could not read from remote repository解决方法
    【技能树笔记】网络篇——练习题解析(五)
    excel导入 Easy Excel
    【微客云】提供视频会员,猫眼,QQ音乐,百度网盘,wps,礼品卡等虚拟权益礼品卡券产品接口
    【C++】多态 ③ ( “ 多态 “ 实现需要满足的三个条件 | “ 多态 “ 的应用场景 | “ 多态 “ 的思想 | “ 多态 “ 代码示例 )
    Mybatis -- 使用
    svn(乌龟svn)和SVN-VS2022插件(visualsvn) 下载
    Android Studio查看第三方库依赖树
    ElastaticSearch -- es之Filters aggregation 先过滤再聚合
  • 原文地址:https://blog.csdn.net/abc19991119/article/details/133266312