pre_delete 信号在特定目录中不起作用

pre_delete signal not working in specific directory

我想在 File 实例 removed.trying 使用 django 信号时从存储中删除文件。这是我的模型文件:

class File(models.Model):
    orig_name = models.CharField(_('Original Name'), max_length=255)
    conversation = models.ForeignKey('conversation.Conversation', on_delete=models.CASCADE)

每个应用程序的架构都是 same.means 所有应用程序都有自己的 signals 目录,在信号目录中我们有 __init__.pyhandlers.py 文件。这里是一个简短的我的应用程序树,其中包含 file 的应用程序的一些详细信息:


 apps
    ├── conversation
    ├── post    
    └── file
        ├── admin.py
        ├── apps.py
        ├── __init__.py
        ├── models.py
        ├── signals
        │   ├── handlers.py
        │   └── __init__.py
        ├── tests.py
        ├── urls.py
        └── views.py

这里是 apps/file/apps.py:

from django.apps import AppConfig


class FileConfig(AppConfig):
    name = 'apps.file' # exact as INSTALLED_APP in setting.py

    def ready(self):
        import apps.file.signals.handers

这里是 apps/file/signals/handlers.py :

from django.db.models.signals import pre_delete
from django.dispatch import receiver
from apps.file.models import File


@receiver(pre_delete, sender=File)
def remove_file_from_storage(sender, instance, *args, **kwargs):
      print('pre_delete signal for File working')
      # some code is here

app/file/signals/__init__.py 文件为空。在这个项目中,我们使用了多个信号,它们都工作正常,但我不知道为什么这个信号不是 working.other 信号来自自定义信号和内置信号。请注意,当我将 def remove_file_from_storage 功能移动到其他应用程序到相关 app_name/signals/handlers.py 时,它正在工作 fine.the 删除过程是一个简单的 generics.DestroyAPIView DRF。我的架构师使用信号的问题在哪里?谢谢

问题是因为您使用 receiver 装饰器来注册信号。因此,您必须将代码放入 Django 应用程序的现成函数中。 This document 确实提到了这一点:

In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator, simply import the signals submodule inside ready().

但在实际操作中,我们不会将所有信号代码都放在 ready 方法中,这可能会使我们的代码更难阅读和更难维护。就像您所做的那样,我们会将信号放在 signals.py 中,然后通过 ready 方法将其加载到您的应用程序中,如下所示:

from django.apps import AppConfig


class FileConfig(AppConfig):
    label = 'file'
    name = 'file'

    def ready(self):
        from apps.file import signals  # NOQA
        # add # NOQA to ignore error message from Python linter when we just import but never used

并将其设置为 __init__.py 以便 Django 可以发现您的应用程序:

 apps
    ├── conversation
    ├── post    
    └── file
        ├── admin.py
        ├── apps.py
        ├── __init__.py # Add to this file
        ├── models.py
        ├── signals
        │   ├── handlers.py
        │   └── __init__.py
        ├── tests.py
        ├── urls.py
        └── views.py
default_app_config = 'apps.file.apps.FileConfig'

您还可以查看 this article 以获得有关 Django 信号的更多详细信息

希望对您有所帮助!