教你如何在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自动连接ssh的方法
Mar 07 Python
python 异常处理总结
Oct 18 Python
使用PyV8在Python爬虫中执行js代码
Feb 16 Python
Python基础之getpass模块详细介绍
Aug 10 Python
Python实现的排列组合计算操作示例
Oct 13 Python
利用Tkinter(python3.6)实现一个简单计算器
Dec 21 Python
解决win64 Python下安装PIL出错问题(图解)
Sep 03 Python
Python实现查找最小的k个数示例【两种解法】
Jan 08 Python
python经典趣味24点游戏程序设计
Jul 26 Python
PyCharm 专业版安装图文教程
Feb 20 Python
Django项目uwsgi+Nginx保姆级部署教程实现
Apr 19 Python
Python Django搭建网站流程图解
Jun 13 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&java(三)
2006/10/09 PHP
PHP个人网站架设连环讲(三)
2006/10/09 PHP
UCenter中的一个可逆加密函数authcode函数代码
2010/07/20 PHP
php的zip解压缩类pclzip使用示例
2014/03/14 PHP
php实现的短网址算法分享
2014/06/20 PHP
php中get_object_vars()方法用法实例
2015/02/08 PHP
利用PHP访问带有密码的Redis方法示例
2017/02/09 PHP
详解将数据从Laravel传送到vue的四种方式
2019/10/16 PHP
jQuery Migrate 1.1.0 Released 注意事项
2014/06/14 Javascript
jQuery实现的兼容性浮动层示例
2016/08/02 Javascript
js弹性势能动画之抛物线运动实例详解
2017/07/27 Javascript
使用vue-infinite-scroll实现无限滚动效果
2018/06/22 Javascript
vue element动态渲染、移除表单并添加验证的实现
2019/01/16 Javascript
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
Python深入学习之内存管理
2014/08/31 Python
使用python绘制常用的图表
2016/08/27 Python
Python之os操作方法(详解)
2017/06/15 Python
django模板语法学习之include示例详解
2017/12/17 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
python 分离文件名和路径以及分离文件名和后缀的方法
2018/10/21 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
德国大型的家具商店:Pharao24.de
2016/10/02 全球购物
彪马英国官网:PUMA英国
2019/02/11 全球购物
给民警的表扬信
2014/01/08 职场文书
美容院考勤制度
2014/01/30 职场文书
中学生自我鉴定
2014/02/04 职场文书
市委常委会班子党的群众路线教育实践活动整改方案
2014/10/25 职场文书
2015年个人剖析材料范文
2014/12/29 职场文书
小学新教师个人总结
2015/02/05 职场文书
汉字听写大会观后感
2015/06/12 职场文书
招商银行工作证明
2015/06/17 职场文书
2019年员工晋升管理制度范本!
2019/07/08 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书
解决goland 导入项目后import里的包报红问题
2021/05/06 Golang
如何使用PostgreSQL进行中文全文检索
2021/05/27 PostgreSQL
Python Pandas读取Excel日期数据的异常处理方法
2022/02/28 Python