Django 的signals(信号)的使用

本文深入解析Django框架中的Signals机制,介绍如何通过Signals实现不同组件间的解耦与通信,包括pre_save、post_save等常见Signals的使用场景及具体实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码实战:https://download.youkuaiyun.com/download/weixin_43692357/11445301

什么是django的signal

django的signal可理解为django内部的钩子,当一个事件发生时,其他程序可对其作出相关反应,可通过signal来回调定义好的处理函数(receivers),从而更大程度的解耦我们的系统。

Django 中常见的signal:

  • pre_save :在调用model的save()方法前发送信号;

  • post_save:在调用model的save()方法之后发送信号;

  • pre_delete: 在调用model的delete()方法之前发送信号;

  • post_delete:在调用model的delete()方法之后发送信号;

    m2m_changed:当多对多一个模型发生改变的时候.

使用场景:

通知是signal最常用的场景之一。例如,在论坛中,在帖子得到回复时,通知楼主。

使用流程:

1 ,在app下新建一个signal_hanger文件.

# 针对model的signal
from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete

from api.models import Student, Student_Log


@receiver(post_save, sender=Student, dispatch_uid="mymodel_post_save")
def student_create_model_handler(sender, **kwargs):
    '''
        创建用户的时候创建用户操作日志
        kwargs:
            { 'using': 'default', 'update_fields': None, 'instance': < Student: Student object >, 'raw': False,
            'created': False, 'signal': < django.db.models.signals.ModelSignal object  at0x7f8f48947400 >}
    '''
    create_bool = kwargs['created']
    instance = kwargs['instance']
    if create_bool:
        Student_Log.objects.create(action='create', name=instance.name)
        print('create action:%s ' % format(instance.name))
    else:
        Student_Log.objects.create(action='update', name=instance.name)
        print('update action:%s' % format(instance.name))



@receiver(post_delete, sender=Student, dispatch_uid="mymodel_post_delete")
def student_delete_model_handler(sender, **kwargs):
    '''
        删除用户的时候创建用户操作日志
        kwargs:
           {'signal': <django.db.models.signals.ModelSignal object at 0x7f5156cf0550>,
           'using': 'default', 'instance': <Student: Student object>}
    '''
    instance = kwargs['instance']
    Student_Log.objects.create(action='delete', name=instance.name)
    print('delete action:%s' % format(instance.name))

2,加载signal

api/__init__py

default_app_config = 'api.apps.MyApiConfig'

api/ apps.py

from django.apps import AppConfig
 
 
class MyApiConfig(AppConfig):
    name = 'api'
 
    def ready(self):
        # signals are imported, so that they are defined and can be used
        import import api.utils.signal_handlers

3,视图中使用

# coding:utf-8
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from api import models
from api.utils.sers import getUserListSerializer
from rest_framework.decorators import action


class StudentViewSetAction(ModelViewSet):
    '''学生视图'''
    queryset = models.Student.objects.all()
    serializer_class = getUserListSerializer  # 数据序列化
    # filter_backends = (
    #     rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)  # 需要用django查询的固定写法
    # filter_class = getUserListFilter  # 定义过滤查询
    # ordering_fields = ('tea', 'id')  # 排序的字段

    def list(self, request, *args, **kwargs):
        '''获取学生列表分页'''
        serializer = self.get_serializer(self.queryset, many=True)
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        '''新增学生信息'''
        models.Student.objects.create(tea_id=1,name='小明',age=12)
        return Response({'method': '新增学生信息'})

    def update(self, request, pk, *args, **kwargs):
        '''修改学生信息'''
        # queryset=models.Student.objects.filter(id__in=[1,2,3,4])
        # print(queryset,len(queryset))
        # models.Student.objects.filter(id=2).update(name='xiaohu')
        obj=models.Student.objects.get(id=2)
        obj.name='xiaohu'
        obj.save()
        return Response({'method': '修改学生信息'})

    def delete(self, request, pk, *args, **kwargs):
        '''删除学生信息'''
        models.Student.objects.get(id=pk).delete()
        return Response({'method': '删除学生信息'})



    @action(methods=['get'], detail=False)
    def read(self, request, *args, **kwargs):
        # """
        #     自定义获取
        pass

    @action(methods=['post'], detail=False)
    def add(self, request, *args, **kwargs):
        """
            自定义新增
        """

        return Response({'method': '这个方法也是新增'})

    @action(methods=['put'], detail=True)
    def edit(self, request, pk, **kwargs):
        """
            自定义修改
        """
        return Response({'method': '这个方法也是修改'})


4,发送请求就能执行相应的signal函数.

参考:https://blog.youkuaiyun.com/hzlnice/article/details/81436289

  •     pre_save:调用model的save()方法前发送信号
  •  
  •     post_save:调用model的save()方法后发送信号
  •     pre_delete:调用model活着QuerySets的delete()方法前发送信号3
  •     post_delete:同理,调用delete()后发送信号
  •     m2m_changed:当一个模型上的ManyToManyField字段被改变的时候发送信号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值