網站首頁 編程語言 正文
Django的信號
Django的信號機制不同于Linux的信號機制,Django 中的信號用于在框架執(zhí)行操作時解耦。當某些動作發(fā)生的時候,系統(tǒng)會根據信號定義的函數執(zhí)行相應的操作
Django的信號主要包含以下三個要素:
- 發(fā)送者(sender):信號的發(fā)出方。
- 信號(signal):發(fā)送的信號本身。
- 接收者(receiver):信號的接收者。
其中接受者就是回調函數,會把這個函數注冊到信號之上。當特定事件發(fā)生之后,發(fā)送者發(fā)送信號,然后執(zhí)行回調函數。
Django信號的使用
查看Django Signal的源碼,看到Django的信號存在以下方法
除了上面的幾個方法,還有幾個屬性
- lock
- recievers
- sender_receivers_cache
- use_caching
根據第一趴介紹知道,要使用Django的信號,需要滿足三要素(發(fā)送者、接受者、和信號)
Django通過
connect()
函數監(jiān)聽
信號,接受發(fā)送者發(fā)送的信號,然后執(zhí)行接受者(回調函數)
Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)
其中
- recievers 是接受者,本質就是一個回調函數
- sender 是發(fā)送信號的主體,如果connect連接的時候,sender 是None(默認也是None)代表該信號接受所有發(fā)送者發(fā)送的該信號;否則只接受具體的發(fā)送者(一個Python對象,比如Django的 Model對象)
- weak – Django 默認將信號處理程序存儲為弱引用。因此,如果你的接收器是本地函數,則可能會對其進行垃圾回收。要防止這種情況發(fā)生,當你要調用 connect() 方法時請傳入 weak=False。
- dispatch_uid 在可能發(fā)送重復信號的情況下,信號接收器的唯一標識符。
具體使用方式
1、需要定義一個回調函數
def my_callback(sender, **kwargs): print("Request finished!")
2、把回調函數
注冊到對應的信號
from django.core.signals import request_finished request_finished.connect(my_callback)
注意這里沒有指定sender,那么就是接受任意發(fā)送者哦
或者更簡單的方式是使用 receiver
函數
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished) def my_callback(sender, **kwargs): print("Request finished!")
或者指定具體的發(fā)送者
from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished, sender="MyTagModel") def my_callback(sender, **kwargs): print("Request finished!")
==> 劃重點
一般我們會把 回調函數
和 信號注冊
放到一個應用的目錄下的 signals.py 文件中去
然后在該應用的 apps.py 中應用
from django.apps import AppConfig from django.core.signals import request_finished class MyAppConfig(AppConfig): ... def ready(self): # Implicitly connect signal handlers decorated with @receiver. from . import signals # Explicitly connect a signal handler. request_finished.connect(signals.my_callback)
這樣只要改應用安裝在 INSTALLED_APPS
中去,那么Django就能識別到具體的信號(包括自定義的信號)以及進行信號的處理(因為已經自動通過 connect進行監(jiān)聽 )
為啥會自動監(jiān)聽呢,當然是 Django的 AppConfig
下的 ready() 函數的作用
自定義信號
首先有個核心點需要明確
所有的信號都是
django.dispatch.Signal
的實例。
比如這里新增一個發(fā)送郵件的信號,每次新增Post之后,發(fā)送郵件給相關訂閱的人
# demoapp/signals.py from django.db.models.signals import post_save from django.dispatch import receiver from .models import Post @receiver(post_save, sender=Post) def send_mail(sender, instance, created, **kwargs): if created: print(f"current instance {instance}") print("Try to send mail to subscriber")
然后把信號導入到 appConfig 的ready() 函數中去
# demoapp/apps.py from django.apps import AppConfig class DemoappConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'demoapp' def ready(self): import demoapp.signals
然后我們在admin注冊Post之后,新增Post,在命令行日志中就能看到
current instance DemoPost First One
Try to send mail to subscriber
[02/Feb/2023 13:47:29] "POST /admin/demoapp/post/add/ HTTP/1.1" 302 0
還有另外一個 主動發(fā)送信號
的方式
1、先定義回調函數 callback_func
2、定義一個信號 mail_send_signal = Signal()
3、回調函數注冊到信號 mail_send_signal.connect(callback_func)
3、主動發(fā)送信號 mail_send_signal.send(sender=xxx, **kwargs)
具體的代碼實現,可以手動嘗試哦,實踐出真知嘛~
擴展:查看Django信號的接受者
Django內置信號的reciever查看
(kfzops) [ 23-02-02 16:04 ] [ colinspace.com ] python manage.py shell Python 3.9.6 (default, Jul 16 2021, 13:41:17) [Clang 12.0.5 (clang-1205.0.22.11)] on darwin Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.db.models.signals import post_migrate >>> post_migrate.receivers [(('django.contrib.auth.management.create_permissions', 4304618416), <weakref at 0x10232b310; to 'function' at 0x10231d1f0 (create_permissions)>), ((4331786592, 4304618416), <weakref at 0x102581e00; to 'function' at 0x10231d160 (create_contenttypes)>)]
擴展:Django內置信號
Django內置了很多有用的信號,大概有以下幾類,可以作為了解。
模型相關的信號
- pre_init
- post_init
- pre_save
- post_save
- pre_delete
- post_delete
- m2m_changed
- class_prepared
其中
1、pre_init/post_init 分別會在模型的__init__()
方法調用 之前/之后發(fā)出
2、pre_save/post_save 分別會在模型的save()
方法調用 之前/之后發(fā)出
3、pre_delete/post_delete 分別會在模型的delete()
方法調用 之前/之后發(fā)出
4、m2m_changed 嚴格意義上來說是由ManyToManyField
字段發(fā)生變化的時候發(fā)出的
5、class_prepared 比較特殊一般不建議用
django-admin 發(fā)出的信號,確切的說是 Django admin在執(zhí)行 python manage.py migrate的時候發(fā)出的信號
- pre_migrete
- post_migrate
顧名思義,不做過多解釋
請求響應信號,也就是Django 發(fā)起request和響應response的信號
- request_started
- request_finished
- get_request_exception
另外還有幾個特殊的信號
1、setting_changed 只有當運行測試用例的時候發(fā)出
2、template_render 當測試系統(tǒng)渲染模板的時候發(fā)出
3、connect_created 當數據庫連接啟動的時候,數據庫管理器發(fā)出
參考文檔
1、 https://docs.djangoproject.com/zh-hans/4.1/topics/signals/
原文鏈接:https://blog.csdn.net/eagle5063/article/details/128873242
相關推薦
- 2022-07-29 Linux文件系統(tǒng)介紹_linux shell
- 2022-01-22 Springboot + Redis 哨兵模式
- 2022-04-18 h5,移動端瀏覽器通過css 實現頁面,元素橫向滾動
- 2022-10-29 python的strip、lstrip、rstrip函數的用法和實例
- 2022-10-02 Selenium+Python自動化測試入門_python
- 2022-12-02 React函數式組件Hook中的useEffect函數的詳細解析_React
- 2022-08-11 boost.asio框架系列之buffer函數_C 語言
- 2022-03-27 Python中Tkinter布局管理grid的使用_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支