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

 

posted on 2023-02-27 19:33  阿明明  阅读(10)  评论(0编辑  收藏  举报