Django中的信号
在现实中,我们会遇到各种各样的需求,比如对客户端请求进行过滤,将满足某些条件的客户端请求过滤掉,此时,我们可以利用Django的中间件来实现该需求,或者,我们希望每次model的save()方法被调用前后,都要写一条日志到日志文件中,此时,我们可以通过Django提供的内置信号post_save来实现,本文我们将要介绍Django的高级功能信号。
信号的概念
简单点说,Django框架内部包含了一个信号调度器,它的作用是可以将框架内部发生的任何操作都通知到功能独立的应用程序,当然,我们也可以缩小发送者和接收者的范围,即指定具体的发送者和接受者,假设我们的程序中有多个业务逻辑都在等待某一个事件发生之后再继续执行后面的代码,那么此时,信号是非常有用的。
使用场景介绍
开始深入研究信号之前,我们先假设这样一种场景:某web站点使用Django开发,现在有一个需求是这样的,每次,当一个客户端请求到来之前和结束之后,都要执行一个函数,这个函数会打印一条Request finished!的消息,我们可以怎么做呢?一种方法是定义一个装饰器,如下代码所示:
from django.shortcuts import render, HttpResponse
# create your views here
def request_finished():
print(“Request finished!”)
def outer(func):
def wrapper(*args, **kwargs):
ret = func(*args, **kwargs)
request_finished()
return ret
return wrapper
@outer
def index(request):
return HttpResponse(“Hello World!”)
但是有了信号之后,我们的解决方法会方便很多!
Django内置了很多高级的信号,提供一些特殊的服务,其中有一个信号名为request_finished,让我们来看看怎么玩。
首先,定义一个接收函数,接收函数可以是任何的Python函数或者方法:
def my_callback(sender, **kwargs):
print(“Request finished!”)
其次,将该接收函数绑定到request_finished信号上,有如下两种方式:
方式一:
from django.core.signals import request_finished
request_finished.connect(my_callback)
方式二:
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished)
def my_callback(sender, **kwargs):
print(“Request finished!”)
def index(request):
return HttpResponse(“Hello World!”)
通过以上简单的两步,我们的my_callback()函数就将在每次请求到来之前和结束之后被调用。
自定义信号
看到这里,很多同学会思考,除了Django框架自带的信号之外,我们可不可以自定义信号呢?是的,答案是肯定的,我们当然可以自定义自己的信号,下面我们来看看如何实现。
首先,自定义信号,所有信号都是django.dispatch.Signal的实例对象,定义一个名为my_signal的信号:
import django.dispatch
my_signal = django.dispatch.Signal()
其次,定义一个接收者receiver,发送信号的时候,该函数将被调用:
from django.dispatch import receiver
@receiver(my_signal)
def my_callback(sender, **kwargs):
print(“Hello World!”)
最后,在你想要发送信号的视图函数中发送信号即可:
from django.shortcuts import render, HttpResponse
def index(request):
my_signal.send(sender=my_signal)
return HttpResponse(“Hello World!”)
至此,以后每一次访问index页面,屏幕上面都将打印Hello World。
Django常用的内置信号介绍
Django内部提供了一组信号,方便用户使用,这些信号包含了一些非常有用的功能,下面来做一个简单介绍:
django.db.models.signals.pre_save & django.db.models.signals.post_save
。每次model的save()方法被调用前后,该信号将被发送。
django.db.models.signals.pre_delete & django.db.models.signals.post_delete
。每次model的delete()方法被调用前后,该信号将被发送。
django.db.models.signals.m2m_changed
。每次ManyToMany字段被修改都会发送该信号。
django.core.signals.request_started & django.core.signals.request_finished
。开始或者结束一个HTTP请求的时候都会发送该信号。
原文地址:https://www.cnblogs.com/paulwhw/p/9380183.html
时间: 2024-11-06 09:47:19