目录
前言
时隔数月,再次更新关于Flask框架的内容。
Flask_信号机制
信号机制
大白话来说,类似于两方属于敌对关系时,某人在敌对方阵营进行交谈,一旦遇到特殊情况,某人便会发送信号,他的同伙接收(监听)到他发的信号后,同伙便会做出一系列的应对策略(进攻|撤退)。
要使用Flask框架中的信号,你需要先安装并导入一个名为"Blinker"的Python库。Blinker是Flask框架中用于处理信号的依赖库。你可以使用以下步骤来安装Blinker:
-
打开终端或命令提示符。
-
运行以下命令来使用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个常用的信号
- template_rendered:模版渲染完成后的信号。
- before_render_template:模版渲染之前的信号。
- request_started:请求开始之前,在到达视图函数之前发送信号。
- request_finished:请求结束时,在响应发送给客户端之前发送信号。
- request_tearing_down:请求对象被销毁时发送的信号,即使在请求过程中发生异常也会发送信号。
- got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。一般可以监听这个信号,来记录网站异常信息。
- appcontext_tearing_down:应用上下文被销毁时发送的信号。
- appcontext_pushed:应用上下文被推入到栈上时发送的信号。
- appcontext_popped:应用上下文被推出栈时发送的信号。
- 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
,以便在请求过程中抛出异常时触发该函数。