目录
前言
时隔数月,再次更新关于Flask框架的内容。
Flask_信号机制
信号机制
大白话来说,类似于两方属于敌对关系时,某人在敌对方阵营进行交谈,一旦遇到特殊情况,某人便会发送信号,他的同伙接收(监听)到他发的信号后,同伙便会做出一系列的应对策略(进攻|撤退)。
要使用Flask框架中的信号,你需要先安装并导入一个名为"Blinker"的Python库。Blinker是Flask框架中用于处理信号的依赖库。你可以使用以下步骤来安装Blinker:
- 1.打开终端或命令提示符。
- 2.运行以下命令来使用pip安装Blinker:
pip install blinker
这将会从Python Package Index(PyPI)下载并安装Blinker库。
自定义信号步骤
创建自定义信号分为三步:
第一是创建一个信号,第二是监听一个信号,第三是发送一个信号。
创建信号
定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间。比如定义一个在访问了某个视图函数的时候的信号。
# Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题 from blinker import Namespace mysignal = Namespace() signal1 = mysignal.signal('信号名称')
这里我们使用signal
函数创建了一个自定义信号 。
监听信号
监听信号:监听信号使用signal1对象的connect方法,在这个方法中需要传递一个函数,用来监听到这个信号后做该做的事情。
def func1(sender,uname): print(sender) print(uname) signal1.connect(func1)
发送信号
signal1.send(uname='momo')
完整代码:
from flask import Flask from blinker import Namespace app = Flask(__name__) #【1】信号机制 3步走 # Namespace:命名空间 #1.定义信号 sSpace = Namespace() fire_signal = sSpace.signal('发送信号火箭') #2.监听信号 def fire_play(sender): print(sender) print("start play") fire_signal.connect(fire_play) #3.发送一个信号 fire_signal.send() if __name__ == '__main__': app.run(debug=True)
小结
Flask框架中的信号(Blinker)机制为我们提供了一种灵活而强大的事件处理功能。过合理利用信号,我们可以实现模块化、可扩展的Web应用程序,并更好地管理和维护代码。
Flask信号使用场景_存储用户登录日志
信号使用场景
定义一个登录的信号,以后用户登录进来以后
就发送一个登录信号,然后能够监听这个信号
在监听到这个信号以后,就记录当前这个用户登录的信息
用信号的方式,记录用户的登录信息即登录日志
导入所需模块和函数和创建登录信号
from blinker import signal from flask import Flask app = Flask(__name__) login_signal = signal('user-login')
我们使用signal
函数创建了一个名为user_logged_in
的信号。该信号将用于在用户登录时触发。
记录登录信息(登录日志)
接下来,我们定义一个信号处理函数,用于记录用户登录信息(登录日志)。
from datetime import datetime @user_logged_in.connect def handle_user_logged_in(sender, user_id, **kwargs): # 记录用户登录信息(登录日志) login_time = datetime.now() log_message = f"用户 {user_id} 于 {login_time} 登录" # 将登录日志写入日志文件或数据库 with open("login_logs.txt", "a") as log_file: log_file.write(log_message + "\n")
我们定义了一个名为handle_user_logged_in的信号处理函数,并使用@user_logged_in.connect装饰器将其与user_logged_in信号绑定。在函数内部,我们获取用户登录时间,并生成登录日志信息。然后,我们可以将该信息写入日志文件或存储到数据库中。
触发登录信号
最后,我们需要在用户登录时触发登录信号。在登录视图函数中,当用户成功登录时,我们可以调用send
方法来触发信号。
from flask import Flask, render_template, request @app.route('/login', methods=['POST']) def login(): # 处理用户登录逻辑 user_id = request.form.get('user_id') # 登录验证逻辑... # 登录成功时触发登录信号 if login_success: user_logged_in.send(user_id=user_id) return "登录成功!" else: return "登录失败!"
当用户登录成功时,我们调用user_logged_in.send(user_id=user_id)
来触发user_logged_in
信号,并将用户ID作为参数传递给信号处理函数。
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的使用
我们将定义一个名为render_function的函数,用于处理模板渲染的信号。这个函数会在模板渲染完成后被调用,并传递三个参数:sender表示发送信号的对象,template表示渲染的模板,context表示模板渲染时使用的上下文数据,使用template_rendered信号连接函数render_function,以便在模板渲染完成时触发该函数。
from flask import Flask,render_template,template_rendered app = Flask(__name__) @app.route('/') def index(): return 'Hello!!' @app.route('/home/') def home(): return render_template('home.html') def render_function(sender,template,context): print(sender) print(template) print(context) template_rendered.connect(render_function) if __name__ =='__main__': app.run(debug=True)
got_request_exception的使用
from flask import Flask,request,got_request_exception,render_template app = Flask(__name__) #内置信号 #got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。 # 一般可以监听这个信号,来记录网站异常信息。 # def request_exception_log(sender,*args,**kwargs): #掌握写参数技巧 # print(sender) # print(args) # print(kwargs) def request_exception_log(sender,exception): print(sender) print(exception) # division by zero got_request_exception.connect(request_exception_log) @app.route('/') def hello_world(): #制造bug a = 1/0 return render_template("index.html",data="momo") if __name__ == '__main__': app.run(debug=True)
我们定义了一个hello_world路由,用于处理根路径'/'的请求。在这个路由中,我们故意制造了一个除以零的错误,以触发异常。然后,我们使用render_template函数来渲染一个名为index.html的模板,并将渲染结果作为响应返回。然后定义了一个名为request_exception_log的函数,用于处理请求过程中抛出的异常。这个函数会在请求过程中抛出异常时被调用,并传递两个参数:sender表示发送信号的对象,exception表示抛出的异常对象。 最后使用got_request_exception信号连接函数request_exception_log,以便在请求过程中抛出异常时触发该函数。