教你如何在Django 1.6中正确使用 Signal


Posted in Python onJune 22, 2014

简单回答是: 在其他方法无法使用的情况下, 才最后考虑使用signal.

因为新的django开发人员得知signal之后, 往往会很高兴去使用它. 他们在能使用signal的地方就使用signal, 并且这是他们觉得自己是django专家一样. 然而, 像这样编码一段时间后, django项目就会变得异常复杂, 许多内容都纠结在一起无法解开.

许多开发者也会将django signal和异步消息列队(例如celery)搞混. signal是同步处理, 因此通过signal调用大处理量的进程时并无法提高性能. 事实上, 将这些需要大处理量的进程移到signal中被视作是一种不好的习惯.

1. 何时使用signal

以下情况不要使用signal:

signal与一个model紧密相关, 并能移到该model的save()时
signal能使用model manager代替时
signal与一个view紧密相关, 并能移到该view中时
以下情况可以使用signal:

signal的receiver需要同时修改对多个model时
将多个app的相同signal引到同一receiver中处理时
在某一model保存之后将cache清除时
无法使用其他方法, 但需要一个被调函数来处理某些问题时
2. Signal的代替方法

使用mod而来manager

以下代码演示了当用户创建Event model时, 需要通知管理员, 如果改写model中的post_save(), 则需要添加额外的逻辑来区分用户还是管理员:

# myapp/managers.py
 from django.db import models

 class EventManager(models.Manager):

 def create_event(self, title, start, end, creator):
 event = self.model(title=title, start=start, end=end, creator=creator)
 event.save()
 event.notify_admins()
 return event

在model中设置model manager:

# myapp/models.py
 from django.conf import settings
 from django.core.mail import mail_admins
 from django.db import models

 from model_utils.models import TimeStampedModel
 from .managers import EventManager

 class Event(TimeStampedModel):

 STATUS_UNREVIEWED, STATUS_REVIEWED = (0, 1)
 STATUS_CHOICES = (
 (STATUS_UNREVIEWED, "Unreviewed"),
 (STATUS_REVIEWED, "Reviewed")
 )

 title = models.CharField(max_length=100)
 start = models.DateTimeField()
 end = model.dateTimeField()
 status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_UNREVIEWED)
 creator = models.ForeignField(settings.AUTH_USER_MODEL)
 objects = EventManager()

 def notify_admins(self):
 subject = "{user} submitted a new event!".format(user=self.creator.get_full_name())
 message = """TITLE: {title}
 START: {start}
 END: {end}""".format(title=self.title, start=self.start, end=self.end)
 mail_admins(subject=subject, message=message, fail_silently=False)

在view中使用create_event()代替create()时, 便会通知管理员了.

在其他代码中验证model

如果你使用pre_save signal来验证某一model, 则应当尝试自己写一个validator取代之. 如果验证是通过ModelForm时, 通过改写clean()实现验证.

使用model的save()和delete()

如果使用pre_save 或 post_save signal, 如果可以, 则将这些代码移到model的save()方法中.

同样如果使用pre_delete 或 post_delete signal, 如果可以, 则将这些代码移到model的delte()方法中.

使用其他代码代替signal

如果可能, 我们可以将signal的逻辑使用其他帮助程序实现.

Python 相关文章推荐
Python实现Windows上气泡提醒效果的方法
Jun 03 Python
Python查询阿里巴巴关键字排名的方法
Jul 08 Python
在Python中使用正则表达式的方法
Aug 13 Python
python对日志进行处理的实例代码
Oct 06 Python
Python多图片合并PDF的方法
Jan 03 Python
numpy linalg模块的具体使用方法
May 26 Python
python+openCV利用摄像头实现人员活动检测
Jun 22 Python
PyQT5 QTableView显示绑定数据的实例详解
Jun 25 Python
python3.6、opencv安装环境搭建过程(图文教程)
Nov 05 Python
简单了解Django项目应用创建过程
Jul 06 Python
Flask-SocketIO服务端安装及使用代码示例
Nov 26 Python
使用pipenv管理python虚拟环境的全过程
Sep 25 Python
python抓取网页时字符集转换问题处理方案分享
Jun 19 #Python
python在linux中输出带颜色的文字的方法
Jun 19 #Python
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
Jun 18 #Python
win7 下搭建sublime的python开发环境的配置方法
Jun 18 #Python
Python写的贪吃蛇游戏例子
Jun 16 #Python
Python中的yield浅析
Jun 16 #Python
python中使用enumerate函数遍历元素实例
Jun 16 #Python
You might like
PHP5权威编程阅读学习笔记 附电子书下载
2012/07/05 PHP
ThinkPHP无限级分类原理实现留言与回复功能实例
2014/10/31 PHP
PHP文件操作方法汇总
2015/07/01 PHP
php等比例缩放图片及剪切图片代码分享
2016/02/13 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
js判断元素是否隐藏的方法
2014/06/09 Javascript
jquery的clone方法应用于textarea和select的bug修复
2014/06/26 Javascript
js实现遮罩层划出效果是生成div而不是显示
2014/07/29 Javascript
jQuery EasyUI中DataGird动态生成列的方法
2016/04/05 Javascript
javascript Promise简单学习使用方法小结
2016/05/17 Javascript
knockoutjs模板实现树形结构列表
2017/07/31 Javascript
Angularjs之ngModel中的值验证绑定方法
2018/09/13 Javascript
浅谈Vue数据响应
2018/11/05 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
微信小程序如何访问公众号文章
2019/07/08 Javascript
Vue 实现分页与输入框关键字筛选功能
2020/01/02 Javascript
使用PYTHON接收多播数据的代码
2012/03/01 Python
使用Python编写简单网络爬虫抓取视频下载资源
2014/11/04 Python
Python中for循环和while循环的基本使用方法
2015/08/21 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
详解Python 解压缩文件
2019/04/09 Python
使用 Django Highcharts 实现数据可视化过程解析
2019/07/31 Python
python爬虫基础之urllib的使用
2020/12/31 Python
个人自我鉴定怎么写
2013/10/28 职场文书
工作失误检讨书范文大全
2014/01/13 职场文书
中国央视网签名寄语
2014/01/18 职场文书
客户经理竞聘演讲稿
2014/05/15 职场文书
大学国际贸易专业自荐信
2014/06/05 职场文书
大学生职业生涯规划大赛作品(精品)
2014/09/17 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
《全神贯注》教学反思
2016/02/22 职场文书
学习型家庭事迹材料(2016精选版)
2016/02/29 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书
毕业季聚会祝酒词!
2019/07/04 职场文书
golang中字符串MD5生成方式总结
2021/07/04 Golang
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python