Django 信号

django 为我们提供了一些预留的函数,去自定义一些操作,比如我们在创建某条数据加入到数据库的时候之前需要做点什么操作,之后需要做点什么操作,这就是信号,如果没有信号,我们自己去写比较麻烦,因为我们用的很多函数都是django为我们封装好了,我们去加自定义的操作的时候可能会涉及到修改源码,这样既不利于我们编写,并且写了耦合性和扩展性都很差,信号很好的给我们提供了扩展的方法.

1.django中自带的信号:

Model signals
    pre_init                    # django的model执行其构造方法前,自动触发
    post_init                   # django的model执行其构造方法后,自动触发
    pre_save                    # django的model对象保存前,自动触发
    post_save                   # django的model对象保存后,自动触发
    pre_delete                  # django的model对象删除前,自动触发
    post_delete                 # django的model对象删除后,自动触发
    m2m_changed                 # django的model中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared              # 程序启动时,检测已注册的app中model类,对于每一个类,自动触发
Management signals
    pre_migrate                 # 执行migrate命令前,自动触发
    post_migrate                # 执行migrate命令后,自动触发
Request/response signals
    request_started             # 请求到来前,自动触发
    request_finished            # 请求结束后,自动触发
    got_request_exception       # 请求异常后,自动触发
Test signals
    setting_changed             # 使用test测试修改配置文件时,自动触发
    template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
    connection_created          # 创建数据库连接时,自动触发

具体用法:

我们先将信号方法注册到程序当中,一般信号我们都心在项目的__init__.py里面,也可以单独写在py文件里面,再在init里面导入也是ok的,让程序一开始就能读到我们写的信号函数,比如写一个请求来的之前我们执行一个函数

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created

#这里写自己要写的函数,名字随意#
def callback(sender, **kwargs):
    print("request_started_callback")
    print('--------------------------------')
    print('操作的类:',sender)
    print('--------------------------------')
    print('连接的信息,参数等:',kwargs)
request_started.connect(callback)####信号函数名字.connect(自己订制的函数名)就连接上了

#其他内置信号都是一样的使用方法,还可以连接多个函数
def callback2(sender,**kwargs):
    print("第二个函数")
request_started.connect(callback2)

自定义信号:

1.创建信号:

import django.dispatch
my_signal= django.dispatch.Signal(providing_args=["sss", "ddd"])
###信号名字自己定义,sss和ddd是参数名字也是自定定义

2.注册信号和内置的信号一样:

from utils.custom_signal import  my_signal#导入信号


def my_callback(sender, **kwargs):#自定义执行函数
    print("my_signal")
    print(sender,kwargs)

my_signal.connect(my_callback)#将函数注册到信号

3.使用

def mysignal(req):
    from fmTest import my_signal#导入信号的位置

    my_signal.send(sender='seven', sss="dd", ddd="sss")#就是使用send方法调用,调用信号 sender 和参数都是自己写
    print("-------------")
    return HttpResponse("ok")

信号的作用就是体现在让代码解耦,让程序简单易懂,扩展性更高.

在代码设计阶段,我们就可以预留信号,方面以后扩展,比如设计一个图书管理系统,设置一个还书时间提醒,以前的时候都是邮箱短信qq等提醒,现在微信用的多了,这时只需要在信号里面加上短信发送的功能,而不需要对源代码做任何修改即可完成功能所需.

原文地址:https://www.cnblogs.com/guoguojj/p/8413536.html