惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
Jina AI
Jina AI
小众软件
小众软件
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
美团技术团队
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东
博客园 - 【当耐特】
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
博客园 - 司徒正美
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
月光博客
月光博客
IT之家
IT之家
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
博客园 - Franky

夜行人

回家路上 第一期的直播演示项目 震动检测器 正能量 在线参观CodeLab Neverland 发布 CodeLab Adapter 3.3.1 DynamicTable 之 纸糊方向盘 CodeLab DynamicTable: 一个可实施的技术方案 CodeLab Insight 发布 Alpha 版 情人节 Home Assistant 周报 && IoT 周报 (02) Joplin: 关注隐私的 Evernote 开源替代软件 浏览器的未来与 Web 传感器 Home Assistant 周报 && IoT 周报 (01) 百宝箱(01) 论自由 介绍 WebThings Home Assistant 周报 && iot 周报 (00) 百宝箱(00) 毛姆读书心得 传世之作 周末徒步 CodeLab Adapter ❤️ Jupyter/Python 航班 躲雨 夏令营途中 [译]思想--作为一种技术 The future of coding 美国之行 三门问题的程序模拟
django笔记之Signals
2014-04-15 · via 夜行人

###Signals是什么

为了回答这个问题,我们先来看下django官网对它的描述:

Django includes a “signal dispatcher” which helps allow decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They’re especially useful when many pieces of code may be interested in the same events.

大概意思是说:Django内部包含了一位“信号调度员”:当某事件在框架内发生时,它可以通知到我们的应用程序(处理函数)。 简而言之,当event(事件)发生时,signals(信号)允许若干 senders(发送者)通知一组 receivers(接收者)。

很像js的事件驱动模型。关于事件驱动,我在上一篇文章中有谈论,这里不多说。

###有什么用的

在web开发中, 你可能会遇到下面这种场景:

在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后, 你要发送一份确认邮件.

如果一个操作可能会触发多个后续事件, 此时使用signals会非常方便. 我们可以想要一下应用场景:

  • sns中的事件通知, 如用户发表了一篇博文, 然后通知所有的好友
  • 用户信息的更改的邮件通知
  • 用户订制信息的邮件通知等

###如何使用

####常用的信号集:

  • django.db.models.signals.pre_save model在save()前发送的信号
  • django.db.models.signals.post_save model在save()后发送的信号
  • django.db.models.signals.pre_delete
  • django.db.models.signals.post_delete

####来自官网的例子

1
2
3
4
5
6
7
#使用装饰器
from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

Connecting to signals sent by specific senders.

就是说我们只处理某个模型发出的信号

1
2
3
4
5
6
7
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel

@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    ...

####自定义事件 在此使用一休哥同学给的例子,也是Django中现成的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#file:django\db\models\signals.py

from django.dispatch import Signal
post_syncdb = Signal(providing_args=["class", "app", "created_models", 
"verbosity", "interactive"])

#-----------------------------------

#file:django\contrib\contenttypes\management.py

from django.db.models import signals
signals.post_syncdb.connect(update_contenttypes)

#-----------------------------------
#file:django\core\management\sql.py

def emit_post_sync_signal(created_models, verbosity, interactive, db):
    # Emit the post_sync signal for every application.
    for app in models.get_apps():
        app_name = app.__name__.split('.')[-2]
        if verbosity >= 2:
            print("Running post-sync handlers for application %s" % app_name)
        models.signals.post_syncdb.send(sender=app, app=app,
            created_models=created_models, verbosity=verbosity,
            interactive=interactive, db=db)

更具体的实例可以参考:django拾遗之signal

###参考

文章作者 种瓜

上次更新 2014-04-15