代码实战: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字段被改变的时候发送信号