项目目录如下

w@w-Vulcan-Series:~/PycharmProjects/beer_server$ tree -I "venv|migrations|__pycache__"
.
├── apps
│   ├── config
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── __init__.py
│   ├── project
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── signals.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── testcase
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── testsuite
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── signals.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   └── user
│       ├── admin.py
│       ├── apps.py
│       ├── __init__.py
│       ├── models.py
│       ├── serializers.py
│       ├── tests.py
│       ├── urls.py
│       └── views.py
├── beer_server
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── LICENSE
├── manage.py
├── README.md
├── requirements.txt

在项目的apps目录下的project目录下新建自定义信号文件signals.py

from django.dispatch import Signal, receiver

# 自定义信号
update_testsuite_to_deleted_signal = Signal(providing_args=['project_instance'])


@receiver(update_testsuite_to_deleted_signal)
def update_testsuite_to_deleted_signal_callback(sender, **kwargs):
    """
    删除项目后,通过信号机制设置该项目下关联的数据的状态为已删除:deleted=True
    """
    testsuite_objs = kwargs['project_instance'].testsuite_set.all()
    if len(testsuite_objs) > 0:
        for testsuite in testsuite_objs:
            testsuite.deleted = True
            testsuite.save()
            for testcase in testsuite.testcase_set.all():
                testcase.deleted = True
                testcase.save()
    config_objs = kwargs['project_instance'].config_set.all()
    if len(config_objs) > 0:
        for config in config_objs:
            config.deleted = True
            config.save()

在project目录下的视图文件views.py中使用该信号

这里我设置的是,当删除project时,触发该信号,发送该信号并携带当前要被删除的project对象,然后再执行自定义信号函数里的代码。

在perform_destroy方法中调用自定义信号的函数

from rest_framework import permissions

from .serializers import ProjectSerializer
from .models import Project
from .signals import update_testsuite_to_deleted_signal
from utils.drf_utils.custom_model_view_set import CustomModelViewSet


# Create your views here.

class ProjectsViewSet(CustomModelViewSet):
    queryset = Project.objects.all().order_by('-id')
    serializer_class = ProjectSerializer
    permission_classes = [permissions.IsAuthenticated]
    my_api_set_tags = ["项目管理"]

    def perform_create(self, serializer):
        serializer.save(creator=self.request.user.username, modifier=self.request.user.username)

    def perform_update(self, serializer):
        serializer.save(modifier=self.request.user.username)

    def perform_destroy(self, instance):
        instance.deleted = True
        instance.save()
        # 删除项目后,通过信号机制设置该项目下关联的数据的状态为已删除:deleted=True
        update_testsuite_to_deleted_signal.send(sender=Project, project_instance=instance)

Q.E.D.


一只鹅啊