Flask高级(四)

目录

前言

Flask_信号机制

信号机制

自定义信号步骤 

创建信号

监听信号

发送信号 

小结

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

信号使用场景

导入所需模块和函数和创建登录信号

 记录登录信息(登录日志)

触发登录信号 

Flask_内置信号

template_rendered的使用

got_request_exception的使用 


前言

时隔数月,再次更新关于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,以便在请求过程中抛出异常时触发该函数。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我还可以熬_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值