教你如何在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中的二维数组的操作方法
May 02 Python
python在指定目录下查找gif文件的方法
May 04 Python
Django admin美化插件suit使用示例
Dec 12 Python
python删除文本中行数标签的方法
May 31 Python
Python3 串口接收与发送16进制数据包的实例
Jun 12 Python
python2和python3实现在图片上加汉字的方法
Aug 22 Python
tensorflow之自定义神经网络层实例
Feb 07 Python
Pandas时间序列:时期(period)及其算术运算详解
Feb 25 Python
Python面向对象魔法方法和单例模块代码实例
Mar 25 Python
Keras之fit_generator与train_on_batch用法
Jun 17 Python
python中有帮助函数吗
Jun 19 Python
Python代码实现双链表
May 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
PHP和XSS跨站攻击的防范
2007/04/17 PHP
表格展示无限级分类(PHP版)
2012/08/21 PHP
PHP生成随机码的思路与方法实例探索
2019/04/11 PHP
在 Laravel 项目中使用 webpack-encore的方法
2019/07/21 PHP
jquery 模拟雅虎首页的点击对话框效果
2010/04/11 Javascript
jQuery教程 $()包装函数来实现数组元素分页效果
2013/08/13 Javascript
jQuery 2.0.3 源码分析之core(一)整体架构
2014/05/27 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
js动态修改表格行colspan列跨度的方法
2015/03/30 Javascript
异步安全加载javascript文件的方法
2015/07/21 Javascript
javascript禁止访客复制网页内容的实现代码
2015/08/05 Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
2016/11/23 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
浅析Node.js非对称加密方法
2018/01/29 Javascript
JavaScript异步加载问题总结
2018/02/17 Javascript
实现jquery放大镜的两种方法
2018/02/22 jQuery
Makefile/cmake/node-gyp中区分判断不同平台的方法
2018/12/18 Javascript
vue实现微信分享链接添加动态参数的方法
2019/04/29 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
ES6 Generator基本使用方法示例
2020/06/06 Javascript
[01:02:38]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第二场 1月10日
2021/03/11 DOTA
python使用Pycharm创建一个Django项目
2018/03/05 Python
Python日志模块logging基本用法分析
2018/08/23 Python
python 获取当前目录下的文件目录和文件名实例代码详解
2020/03/10 Python
Pycharm中切换pytorch的环境和配置的教程详解
2020/03/13 Python
彪马英国官网:PUMA英国
2019/02/11 全球购物
碧欧泉法国官网:Biotherm法国
2019/10/23 全球购物
怎样写好自荐信和推荐信
2013/12/26 职场文书
财务支持类个人的自我评价
2014/02/14 职场文书
行政助理的岗位职责
2014/02/18 职场文书
本溪关门山导游词
2015/02/09 职场文书
导游词300字
2015/02/13 职场文书
信用卡工资证明范本
2015/06/19 职场文书
Python趣味实战之手把手教你实现举牌小人生成器
2021/06/07 Python
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js
CSS 实现磨砂玻璃(毛玻璃)效果样式
2023/05/21 HTML / CSS