教你如何在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用list或dict字段模式读取文件的方法
Jan 10 Python
python实现对文件中图片生成带标签的txt文件方法
Apr 27 Python
pycharm配置pyqt5-tools开发环境的方法步骤
Feb 11 Python
python实现矩阵打印
Mar 02 Python
python实现批量处理将图片粘贴到另一张图片上并保存
Dec 12 Python
python离线安装外部依赖包的实现
Feb 13 Python
解决Python logging模块无法正常输出日志的问题
Feb 21 Python
Python的PIL库中getpixel方法的使用
Apr 09 Python
Python如何爬取51cto数据并存入MySQL
Aug 25 Python
Matplotlib配色之Colormap详解
Jan 05 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
Feb 18 Python
Python djanjo之csrf防跨站攻击实验过程
May 14 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
PHP中redis的用法深入解析
2014/02/20 PHP
PHP进阶学习之Geo的地图定位算法详解
2019/06/19 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
JS 非图片动态loading效果实现代码
2010/04/09 Javascript
js动态在form上插入enctype=multipart/form-data的问题
2012/05/24 Javascript
基于datagrid框架的查询
2013/04/08 Javascript
JQuery的自定义事件代码,触发,绑定简单实例
2013/08/01 Javascript
巧用replace将文字表情替换为图片
2014/04/17 Javascript
让angularjs支持浏览器自动填表
2014/11/10 Javascript
jQuery中removeData()方法用法实例
2014/12/27 Javascript
AngularJS基础 ng-src 指令简单示例
2016/08/03 Javascript
利用原生JS与jQuery实现数字线性变化的动画
2017/02/24 Javascript
Node.JS更改Windows注册表Regedit的方法小结
2017/08/18 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
react+ant design实现Table的增、删、改的示例代码
2018/12/27 Javascript
微信小程序返回上一级页面的实现代码
2020/06/19 Javascript
在elementui中Notification组件添加点击事件实例
2020/11/11 Javascript
使用Python的Twisted框架编写简单的网络客户端
2015/04/16 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
Pyqt5实现英文学习词典
2019/06/24 Python
Python爬虫学习之翻译小程序
2019/07/30 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
2020/11/17 Python
Autopep8的使用(python自动编排工具)
2021/03/02 Python
HTML5+CSS设置浮动却没有动反而在中间且错行的问题
2020/05/26 HTML / CSS
台湾演唱会订票网站:StubHub台湾
2019/06/11 全球购物
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
初二政治教学反思
2014/01/12 职场文书
小学教师培训方案
2014/06/09 职场文书
群众路线对照检查材料思想汇报怎么写
2014/09/18 职场文书
事业单位人员的自我评价范文
2014/09/21 职场文书
安全先进个人材料
2014/12/29 职场文书
个人年度总结报告
2015/03/09 职场文书
六年级上册《闻官军收河南河北》的教学设计
2019/11/15 职场文书
python 镜像环境搭建总结
2022/09/23 Python