教你如何在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在校内发人人网状态(人人网看状态)
Feb 19 Python
Python中使用copy模块实现列表(list)拷贝
Apr 14 Python
python通过ftplib登录到ftp服务器的方法
May 08 Python
纯python实现机器学习之kNN算法示例
Mar 01 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
Mar 13 Python
python list转矩阵的实例讲解
Aug 04 Python
推荐10款最受Python开发者欢迎的Python IDE
Sep 16 Python
Python之lambda匿名函数及map和filter的用法
Mar 05 Python
在pyqt5中QLineEdit里面的内容回车发送的实例
Jun 21 Python
python实现连连看辅助之图像识别延伸
Jul 17 Python
python中编写函数并调用的知识点总结
Jan 13 Python
Python中request的基本使用解决乱码问题
Apr 12 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
Search File Contents PHP 搜索目录文本内容的代码
2010/02/21 PHP
jQuery Mobile + PHP实现文件上传
2014/12/12 PHP
PHP实现二维数组根据key进行排序的方法
2016/12/30 PHP
基于jQuery架构javascript基础体系
2011/01/01 Javascript
JS打开图片另存为对话框实现代码
2012/12/26 Javascript
JavaScript 函数惰性载入的实现及其优点介绍
2013/08/12 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/08/22 Javascript
JavaScript计时器示例分析
2015/02/05 Javascript
Jquery的基本对象转换和文档加载用法实例
2015/02/25 Javascript
css如何让浮动元素水平居中
2015/08/07 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
jQuery焦点图左右转换效果
2016/12/12 Javascript
node.js 发布订阅模式的实例
2017/09/10 Javascript
手机注册发送验证码倒计时的简单实例
2017/11/15 Javascript
Vue2.0 事件的广播与接收(观察者模式)
2018/03/14 Javascript
详解Vue.js中.native修饰符
2018/04/24 Javascript
vue移动端实现红包雨效果
2020/06/23 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
2020/07/17 Javascript
[01:28:56]2014 DOTA2华西杯精英邀请赛 5 24 CIS VS DK
2014/05/26 DOTA
删除目录下相同文件的python代码(逐级优化)
2012/05/25 Python
Python写入CSV文件的方法
2015/07/08 Python
基于python的七种经典排序算法(推荐)
2016/12/08 Python
老生常谈Python进阶之装饰器
2017/05/11 Python
Python常见字典内建函数用法示例
2018/05/14 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
Python从Excel中读取日期一列的方法
2018/11/28 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
Python基于Tkinter编写crc校验工具
2020/05/06 Python
Anthropologie英国:美国家喻户晓的休闲服装和家居产品品牌
2018/12/05 全球购物
英国领先的鞋类零售商:Shoe Zone
2018/12/13 全球购物
服装销售人员求职自我评价
2013/09/26 职场文书
室内设计自我鉴定
2013/10/15 职场文书
趣味活动策划方案
2014/02/08 职场文书
法人委托书
2014/07/31 职场文书
写给老师的感谢信
2015/01/20 职场文书