这是在Django 1.7发布时添加到文档中的:
严格来说,信号处理和注册代码可以放在任何你喜欢的地方,尽管建议避免应用程序的根模块及其模型模块,以尽量减少导入代码的副作用。
在实践中,信号处理程序通常定义在与它们相关的应用程序的信号子模块中。信号接收器连接在应用程序配置类的 ready() 方法中。如果您使用的是 receiver() 装饰器,只需在 ready() 中导入信号子模块。
Django 1.7 中的更改:由于以前版本的 Django 中不存在 ready(),因此信号注册通常发生在模型模块中。
最佳实践是在信号子模块中的 handlers.py 中定义您的处理程序,例如一个看起来像这样的文件:
yourapp/signals/handlers.py:
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel
@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
pass
注册信号处理程序的最佳位置是在定义它的应用程序的 AppConfig 中,使用ready()方法。这将如下所示:
你的应用程序/apps.py:
from django.apps import AppConfig
class TasksConfig(AppConfig):
name = 'tasks'
verbose_name = "Tasks"
def ready(self):
import yourproject.yourapp.signals.handlers #noqa
确保通过直接在 settings.py 的 INSTALLED_APPS 或__init__
应用程序中指定来加载 AppConfig。有关更多信息,请参阅 ready() 文档。
注意:如果您也为其他应用程序提供信号来监听,请将它们放在__init__
您的信号模块中,例如一个看起来像这样的文件:
yourapp/signals/__init__.py
import django.dispatch
task_generate_pre_save = django.dispatch.Signal(providing_args=["task"])
然后,另一个应用程序可以通过导入和注册来收听您的信号,例如from yourapp.signals import task_generate_pre_save
. 将信号与处理程序分开可以保持干净。
Django 1.6 的说明:
如果您仍然停留在 Django 1.6 或更低版本,那么您会做同样的事情(在 yourapp/signals/handlers.py 中定义您的处理程序),但不是使用 AppConfig,而是通过 __init__.py 加载处理程序您的应用程序,例如:
你的应用程序/__init__.py
import signals
这不如使用 ready() 方法好,因为它经常导致循环导入问题。