Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django pre_删除信号被忽略_Python_Django_Django Signals - Fatal编程技术网

Python Django pre_删除信号被忽略

Python Django pre_删除信号被忽略,python,django,django-signals,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.m

以下是在模型文档的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)

那么问题是什么呢?我应该在那里再进口点什么吗?或者我应该将此文件导入到某个地方吗?

问题是,如果您将其放入
signals.py
(推荐)中,但不执行任何操作,则没有人会导入该文件

你应该特别注意

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

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


完整程序应为:

# my_app/__init__.py

default_app_config = 'my_app.apps.ConfigForMyApp'
# 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
apps.py应该是:

# my_app/__init__.py

default_app_config = 'my_app.apps.ConfigForMyApp'
# 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

尽管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文件。但是,是的,如果信号连接的数量增加,那么在应用程序配置中管理它们就更容易了

谢谢,这很有效。它值得额外的复杂性吗?把它留在模型中有什么不对吗?这取决于你计划在多大程度上发展你的应用程序。如果它不会增长,则将其保留在
模型中。如果你计划重新发布它,使用一堆迁移的东西,一些奇怪的连接,添加单元测试等等,那么它可能是值得做的,因为你可能会避免一些错误,代码会更干净整洁。谢谢,如果我希望它是全系统的(与特定的应用无关),我应该把它们不放在应用程序目录中,但是在projectapps.py和init中,这也期望删除
@接收的
装饰器,不是吗?它确实提供了更干净的代码,尽管模型加载时信号连接的潜在问题可能仍然是一个问题。但是,+1:)