Django中的信号就是字面意思,当发送某个信号的时候,就会触发一个或者多个函数的执行,例如,当我们每次发送短信的时候,我们可能需要将验证码保存在redis中,同时需要记录在log中,此时我们就可以实现一个信号,信号中定义了验证码的保存和log日志的记录,在每次发送短信之后,发送信号即可
使用信号在一定程度上可以帮助我们实现解耦
信号的使用流程
- 自定义一个信号
- 注册信号
- 触发信号
示例如下
# encoding:utf-8
# author:kunmzhao
# email:1102669474@qq.com
from django import dispatch
# 1.自定义信号
my_signal = dispatch.Signal()
# 2.注册信号
def save_code_to_redis(sender, **kwargs):
print("保存验证码", sender, kwargs)
def save_log(sender, **kwargs):
print("保存日志", sender, kwargs)
my_signal.connect(save_code_to_redis)
my_signal.connect(save_log)
# 执行信号
my_signal.send("demon")
执行结果

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中modal类,对于每一个类,自动触发
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 # 创建数据库连接时,自动触发
注册信号
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("xxoo_callback")
post_save.connect(callback)
触发信号
from app01 import models
def demo(request):
models.NewBB.objects.create(name='v1')
return HttpResponse("ok")
面试题:如何在数据库中插入一条数据的时候进行Log的记录?
答案就是通过信号来实现,以下是代码详情
视图
from app01 import models
from rest_framework.viewsets import ModelViewSet
from rest_framework import serializers
from django.db.models.signals import pre_save
# 定义保存日志的代码
def perform_insert_data(sender, **kwargs):
instance = kwargs["instance"]
print("保存数据", sender)
print("姓名:{}".format(instance.name))
print("年龄:{}".format(instance.age))
class StudentModelSerializers(serializers.ModelSerializer):
class Meta:
model = models.Student
fields = "__all__"
# Create your views here.
class Student(ModelViewSet):
queryset = models.Student.objects.all().order_by('-id')
serializer_class = StudentModelSerializers
def perform_create(self, serializer):
# 注册保存信号
pre_save.connect(perform_insert_data)
serializer.save()
模型类
from django.db import models
# Create your models here.
class Student(models.Model):
name = models.CharField(verbose_name="学生姓名", max_length=32)
age = models.SmallIntegerField(verbose_name="学生年龄")
控制台输出
保存数据 <class 'app01.models.Student'> 姓名:kunmzhao 年龄:23
浙公网安备 33010602011771号