教你如何在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之字典,你还记得吗?
Sep 20 Python
Python中列表、字典、元组、集合数据结构整理
Nov 20 Python
python实现批量改文件名称的方法
May 25 Python
Python回调函数用法实例详解
Jul 02 Python
python遍历小写英文字母的方法
Jan 02 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
Jun 03 Python
python实现简单五子棋游戏
Jun 18 Python
Python PIL读取的图像发生自动旋转的实现方法
Jul 05 Python
使用python实现滑动验证码功能
Aug 05 Python
python中的 zip函数详解及用法举例
Feb 16 Python
Python实现列表拼接和去重的三种方式
Jul 02 Python
实战Python爬虫爬取酷我音乐
Apr 11 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
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
同域jQuery(跨)iframe操作DOM(实例讲解)
2013/12/19 Javascript
js中reverse函数的用法详解
2013/12/26 Javascript
JavaScript实现的使用键盘控制人物走动实例
2014/08/27 Javascript
Bootstrap自定义文件上传下载样式
2016/05/26 Javascript
nodejs基础知识
2017/02/03 NodeJs
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
JS变量中有var定义和无var定义的区别以及es6中let命令和const命令
2017/02/19 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
JS实现队列的先进先出功能示例
2017/05/10 Javascript
JavaScript解析任意形式的json树型结构展示
2017/07/23 Javascript
微信小程序中吸底按钮适配iPhone X方案
2017/11/29 Javascript
基于Vue的SPA动态修改页面title的方法(推荐)
2018/01/02 Javascript
Vue.js 点击按钮显示/隐藏内容的实例代码
2018/02/08 Javascript
基于vue2.0动态组件及render详解
2018/03/17 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
vue 对象添加或删除成员时无法实时更新的解决方法
2019/05/01 Javascript
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
你知道JavaScript Symbol类型怎么用吗
2020/01/08 Javascript
Python爬虫辅助利器PyQuery模块的安装使用攻略
2016/04/24 Python
python实现图书借阅系统
2019/02/20 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
解决ROC曲线画出来只有一个点的问题
2020/02/28 Python
python Matplotlib模块的使用
2020/09/16 Python
DBA数据库管理员JAVA程序员架构师必看
2016/02/07 面试题
法律六进活动方案
2014/03/13 职场文书
大学社团活动总结
2014/04/26 职场文书
音乐之声音乐广播稿
2014/09/10 职场文书
个人职业及收入证明
2014/10/13 职场文书
化验员岗位职责
2015/02/14 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
战友聚会致辞
2015/07/28 职场文书
56句经典英文座右铭
2019/08/09 职场文书
python关于集合的知识案例详解
2021/05/30 Python
HTML 里 img 元素的 src 和 srcset 属性的区别详解
2023/05/21 HTML / CSS