未调用 Django + DjangoCMS 信号处理程序

Django + DjangoCMS signal handlers not being called

因此,在 Django 1.7.7 中引入了一种处理信号的新方法。我在 Python 上使用 1.7.7django_cms,运行 2.

我正在尝试实施这种新方法,尽管文档很少但足够简单,但它只是行不通。我认为 Django-CMS 或其插件之一与它有关。

我想做的是,对于 MyModelpre_save 信号中保存的每个 MyModel,我的 CounterModel 的计数器增加 1模型.

我得出的结论是它不起作用,因为 increase_counter 函数中的 raise Exception('it runs') 没有被引发..

我有以下内容:

myapp/models/mymodel.py

from .counter_model import CounterModel
# Imports here

class MyModel(models.Model):
    name = models.CharField(max_length=128)
    categories = models.ManyToManyField(CounterModel)

myapp/models/counter_model.py

# Imports here

class CounterModel(models.Model):
    amount_of_mymodels = models.PositiveIntegerField(default=0)

myapp/signals.py

from .models.mymodel import MyModel
# Other imports here

@receiver(pre_save, sender=MyModel)
def increase_counter(sender, **kwargs):
    instance = kwargs.get('instance')
    for category in instance.categories.all():
        category.amount_of_mymodels += 1

myapp/apps.py

from django.apps import AppConfig
# Other imports here

class MyAppConfig(AppConfig):
    name = "myapp"

    def ready(self):
        import myapp.signals

myapp/__init__.py

default_app_config = 'myapp.apps.MyAppConfig'

我的 apps.py 中的 import signals 被执行,因为当我在那里引发异常时,它在我的控制台中引发(在 ready() 函数中)。

希望有人能澄清我遇到的这个问题!

顺便说一句: 我也添加了 myapp 到我的 INSTALLED_APPS

更新: 我在另一个项目(Python 3,还有 Django 1.7)中尝试了新的信号方法,它工作正常。如果有人知道什么可能导致我的其他项目中的信号失败,请告诉我!我现在要尝试调试它,感谢各种形式的帮助。

注意:对于每个认为'for循环可能为空,打印一些东西'的人,请注意开头的以下内容我的问题:我得出的结论是它不起作用,因为 increase_counter 函数中的 raise Exception('it runs') 没有被引发..。谢谢!

修复 1

我通过将 signals.py 代码放入 models.py 来测试您的代码并且它有效。

这是为什么?

来自Django docs

Where should this code live?

Strictly speaking, signal handling and registration code can live anywhere you like, although it's recommended to avoid the application's root module and its models module to minimize side-effects of importing code.

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().

修复 2

如果您不想将 signals.py 代码放入 models.py,您可以这样做以下

class MyAppConfig(...):
   ...

    def ready(self):
        # you've to import your app's signals.py 
        # not Django's signals module
        import myapp.signals

编辑

关于这个问题有一些很棒的答案和备选方案:the right place to keep my signals.py files in django

在我所有的 CMS 项目中,我都使用简单的 import signals 作为我 models.py 的最后一行,因为尝试在其他任何地方导入似乎会导致问题。我不喜欢这种方法,但我在接收信号方面从未遇到过任何问题,而且目前还没有找到更好的解决方案。我的大多数项目都是使用 django 1.6 和 1.7 在 CMS 3 后期构建的。

考虑到它的进展,这个问题有点难以理解,所以如果我遗漏了什么,请发表评论。