在Django 1.7发布时,它已添加到文档中:
严格来说,信号处理和注册代码可以存在于您喜欢的任何位置,尽管建议避免使用应用程序的根模块及其模型模块,以最大程度地减少导入代码的副作用。
实际上,信号处理程序通常是在与之相关的应用程序的信号子模块中定义的。信号接收器连接在应用程序配置类的ready()方法中。如果您使用的是receiver()装饰器,则只需将信号子模块导入ready()即可。
在Django 1.7中进行了更改:由于在早期版本的Django中不存在ready(),因此信号注册通常发生在models模块中。
最佳实践是在信号子模块中的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
然后,使用ready()方法在定义它的应用程序的AppConfig中注册信号处理程序的最佳位置。看起来像这样:
yourapp / 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加载处理程序。您的应用,例如:
yourapp / __ init__.py
import signals
这不如使用ready()方法好,因为它经常会引起循环导入问题。