Django pre_delete信号被忽略了

时间:2016-01-22 13:41:50

标签: python django django-signals

这是在模型文档的pre_delete上运行的内容。当根据建议的最佳实践放入单独的文件(signals.py)时,此代码会被皇家忽略。当放入模型文件时,它工作正常。

from django.db.models.signals import pre_delete, pre_save
from django.dispatch import receiver
from _myTools.functions import ImageProcessing
from content_image.models import Document
import os

# Image deletion when deleting entire entry
@receiver(pre_delete, sender=Document, dispatch_uid='document_delete_signal')
def entry_deletion_images_delete(sender, instance, using, **kwargs):
    for key, value in instance.imageSizes.items():
        name_of_image_field = str(getattr(instance, key))  # Converts to string, if not is object itself
        os.remove(instance.baseDir + name_of_image_field)
        setattr(instance, key, None)

那么问题是什么?我应该在那里进口更多东西吗?或者我应该在某处导入此文件?

2 个答案:

答案 0 :(得分:2)

问题在于,如果你把它放在signals.py(按照推荐)但不做任何其他事情,那么没有人会导入该文件。

您应该关注this advice,特别是

  

实际上,信号处理程序通常定义在与其相关的应用程序的信号子模块中。信号接收器在应用程序配置类的ready()方法中连接。如果您正在使用receiver()装饰器,只需在ready()内导入信号子模块。

ready()负责导入模块,从而激发信号“连接”并允许信号接收器工作。

完整的程序应该是:

# my_app/__init__.py

default_app_config = 'my_app.apps.ConfigForMyApp'

,apps.py应为:

# my_app/apps.py

from django.apps import AppConfig

class ConfigForMyApp(AppConfig):
    # Optionally add `name` and `verbose_name`
    # for the app
    def ready(self): # overriding the ready method
        # This will trigger the @receiver decorator 
        # and thus connect the signals
        import my_app.signals

答案 1 :(得分:2)

虽然MariusSiuram提供的答案是django> = 1.7的新推荐方式,但这里有另一种模式,无论django版本如何都可以使用:

在models.py文件中:

from django.db.models.signals import pre_delete
from myapp.signals import pre_delete_signal_dispatcher

pre_delete.connect(pre_delete_signal_dispatcher, sender=MyModel, dispatch_uid="delete_signal_dispatch")

这样,在解析models.py文件时会连接信号,并在pre_delete事件上触发,您可以继续增加signals.py文件。但是,是的,如果信号连接数量增加,则在app config中管理它们会更容易。