Django 信号signal
序言
Django自带一套信号机制来帮助我们在框架的不同应用位置之间传递信息。也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将信号(signals)发送给一组接收者(receivers),此时接收者进行一些相关处理动作。
信号系统包含以下三要素:
- 信号:Signal对象
- 发送者:信号发出方
- 接收者:信号接收方
Django内置了一整套信号,下面是一些比较常用的:
- pre_save & post_save 在ORM模型的save()方法调用之前或之后发送信号
- pre_delete & post_delete 在ORM模型或查询集的delete()方法调用之前或之后发送信号
- request_started & request_finished 当接收和关闭HTTP请求时发送信号
- m2m_changed 当多对多字段被修改时发送信号
以上可以看出,在某种程度上说,信号和数据库触发器有些相似。
接下来看看Django信号如何使用,可分为内置信号和自定义信号。
使用内置信号
内置信号使用起来很简单,最方便的是采用receiver装饰器。
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished, sender=Myclass) def signal_handler(sender, **kwargs): # 接收到信号后,在此处理 print("请求完成!")
装饰器将处理函数注册成接收器,当内置信号发送后,此处理函数立即执行。
使用自定义信号
首先在根URLConf中写一条路由:
# 信号测试 url(r'^signal/$', signal_sender),
自定义一个信号:
from django.dispatch import receiver, Signal signal_obj = Signal(['hostname', 'msg', 'time']) # 实例化信号对象,绑定一些信号属性
编写视图:
import datetime import os import django from django.dispatch import receiver, Signal from django.http import HttpResponse # 发送信号 def signal_sender(request): hostname = request.get_host() msg = 'Django Signal Test' time = datetime.date.today() signal_obj.send(sender=signal_sender, hostname=hostname, msg=msg, time=time) # 关键一行 return HttpResponse('200 OK') # 接收和处理信号 @receiver(signal_obj, sender=signal_sender) # 装饰器把处理函数注册成接收器 def signal_handler(sender, **kwargs): # 接收到信号后,在此处理。kwargs字典用来传递Signal信号参数 print('接收到信号内容:{hostname}|"{msg}"|{time}'.format(hostname=kwargs['hostname'], msg=kwargs['msg'], time=kwargs['time']))
现在可以测试一下,python manage.py runserver启动服务器。浏览器中访问 http://127.0.0.1:8000/signal/。重点不在浏览器的返回,而在后台Terminal返回的内容:
接收到信号内容:www.wcwnina.com:8888|"Django Signal Test"|2018-12-08
至此。转载请注明出处。