教你如何在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+django+sql学生信息管理后台开发
Jan 11 Python
python 删除指定时间间隔之前的文件实例
Apr 24 Python
Python IDLE清空窗口的实例
Jun 25 Python
PyCharm代码提示忽略大小写设置方法
Oct 28 Python
Python3中函数参数传递方式实例详解
May 05 Python
解决Python内层for循环如何break出外层的循环的问题
Jun 24 Python
linux环境中没有网络怎么下载python
Jul 07 Python
Python中变量的输入输出实例代码详解
Jul 28 Python
python打印直角三角形与等腰三角形实例代码
Oct 20 Python
python构建指数平滑预测模型示例
Nov 21 Python
用python 绘制茎叶图和复合饼图
Feb 26 Python
python实现高效的遗传算法
Apr 07 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 常用函数库和一些实用小技巧
2009/01/01 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
Codeigniter中禁止A Database Error Occurred错误提示的方法
2014/06/12 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
javascript事件问题
2009/09/05 Javascript
JavaScript判断窗口是否最小化的代码(跨浏览器)
2010/08/01 Javascript
JS无限极树形菜单,json格式、数组格式通用示例
2013/07/30 Javascript
JavaScript常用判断写法大全(推荐)
2016/05/30 Javascript
微信小程序 教程之列表渲染
2016/10/18 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
2017/11/14 Javascript
jQuery实现的导航条点击后高亮显示功能示例
2019/03/04 jQuery
Node绑定全局TraceID的实现方法
2019/11/14 Javascript
jQuery zTree如何改变指定节点文本样式
2020/10/16 jQuery
vue中使用router全局守卫实现页面拦截的示例
2020/10/23 Javascript
Vue仿Bibibili首页的问题
2021/01/21 Vue.js
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
[06:16]DOTA2守卫传承者——职业选手谈心路历程
2015/02/26 DOTA
python操作xml文件示例
2014/04/07 Python
django利用request id便于定位及给日志加上request_id
2018/08/26 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
在PyTorch中使用标签平滑正则化的问题
2020/04/03 Python
keras.utils.to_categorical和one hot格式解析
2020/07/02 Python
Python 执行矩阵与线性代数运算
2020/08/01 Python
pycharm 实现复制一行的快捷键
2021/01/15 Python
CSS3移动端vw+rem不依赖JS实现响应式布局的方法
2019/01/23 HTML / CSS
HTML5 Canvas中使用路径描画二阶、三阶贝塞尔曲线
2015/01/01 HTML / CSS
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
大学生未来职业生涯规划书
2014/02/15 职场文书
设计顾问服务计划书
2014/05/04 职场文书
民政局办理协议离婚(范本)
2014/10/25 职场文书
工作失职自我检讨书
2015/05/05 职场文书
2016年学校招生广告语
2016/01/28 职场文书
医学会议开幕词
2016/03/03 职场文书
《艾尔登法环》Boss腐烂树灵很有可能是《黑暗之魂3》的一个废案
2022/04/11 其他游戏