django信号
应用场景:
1. 通知类信号:
比如某人评论了该文章,要通知作者。但是可以在保存该评论时,就通知作者,但是这样的话,不利于解耦,不利于后期维护。如果我们在保存评论时,只发一个简单的信号,外部的通知逻辑拿到信号后,再发送通知,这样评论的逻辑和通知的逻辑做到了分开,后期维护扩展都比较容易。
2. 初始化类
事件完成后,做一系列的初始化工作。
3. 其他一些使用场景总结
以下情况不要使用signal:
- signal与一个model紧密相关, 并能移到该model的save()时
- signal能使用model manager代替时
- signal与一个view紧密相关, 并能移到该view中时
以下情况可以使用signal:
- signal的receiver需要同时修改对多个model时
- 将多个app的相同signal引到同一receiver中处理时
- 在某一model保存之后将cache清除时
无法使用其他方法, 但需要一个被调函数来处理某些问题时
使用
- signal
就是定义信号的一些参数。比如以下是django内置的一些信号,用于model操作时触发
- signal
pre_save = ModelSignal(providing_args=["instance", "raw", "using", "update_fields"],
use_caching=True)
post_save = ModelSignal(providing_args=["instance", "raw", "created", "using", "update_fields"], use_caching=True)
pre_delete = ModelSignal(providing_args=["instance", "using"], use_caching=True)
post_delete = ModelSignal(providing_args=["instance", "using"], use_caching=True)
还可以自定义信号
import django.dispatch
my_signal = django.dispatch.Signal(providing_args=["arg1","arg2"])
# 这个信号可以传递两个参数arg1和arg2过来
触发信号
django内置的一些信号会自动触发。自己定义的信号,就需要自己触发了。
my_signal.send(sender="test func",arg1="111",arg2="222")
- receiver
上面说了那么多,似乎还没提到信号触发过来该怎么接受,怎么处理。
#apps.py
from django.apps import AppConfig
class App01Config(AppConfig):
name = 'app01'
def ready(self):
import app01.signals.receiver
需要重写ready函数,导入信号接受处理的文件
接受处理方式
# receiver.py
from django.dispatch import receiver
# 导入django 内置的信号
from django.core.signals import request_finished
from django.db.models.signals import post_save
# 导入自定义的信号
from app01.signals.signals import my_signal
# 两种绑定信号的方式,两种都会触发。
@receiver(request_finished )
def my_signals_handler_1(sender,**kwargs):
print(sender)
print(kwargs)
print("request over")
def my_signals_handler_2(sender,**kwargs):
print("request over 2 ")
request_finished.connect(my_signals_handler_2)
@receiver(my_signal)
def my_custom_handler(sender,**kwargs):
print(sender)
print(kwargs)
print("custom over")
总结
这样可以使用django的信号 来审计用户操作。
或者去做一些通知性的工作。
但是要主要这些都是同步的操作。如果比较耗时的,是不建议放到信号里去处理的。