将我的signals.py文件保存在django中的正确位置
基于我从django网站阅读的文档,它似乎像应用程序文件夹中的signals.py是一个很好的开始,但是我面临的问题是,当我为pre_save创build信号,我尝试导入类从模型,与模型中任务的导入操作冲突。 看到我的代码如下
model.py
from django.contrib.auth.models import User from django.db import models from django.utils.translation import gettext as _ from signals import * class Comm_Queue(CommunicatorAbstract): queue_statuses = ( ('P', _('Pending')), ('S', _('Sent')), ('E', _('Error')), ('R', _('Rejected')), ) status = models.CharField(max_length=10, db_index=True, default='P') is_html = models.BooleanField(default=False) language = models.CharField(max_length=6, choices=settings.LANGUAGES) sender_email = models.EmailField() recipient_email = models.EmailField() subject = models.CharField(max_length=100) content = models.TextField() signals.py
 from django.conf import settings from django.db.models.signals import pre_save from django.dispatch import receiver from models import Comm_Queue @receiver(pre_save, sender=Comm_Queue) def get_sender_email_from_settings(sender, **kwargs): obj=kwargs['instance'] if not obj.sender_email: obj.sender_email='%s' % settings.ADMINS[0][1] 
这段代码将不会运行,因为我在信号里面导入了Comm_queue,并且正在执行*导入到models.py中的信号。 可以任何一个build议,我怎么能过来这个问题?
问候,
Django的原始答案<1.7:
 您可以通过在应用程序的__init__.py文件中导入signals.py来注册信号: 
 # __init__.py import signals 
 这将允许从signals.py导入models.py而没有循环导入错误。 
这种方法存在的一个问题是,如果使用coverage.py,则会掩盖覆盖率结果。
相关讨论
编辑:对于Django> = 1.7:
 自引入AppConfig以来,推荐的导入信号的方式就是init()函数。 请参阅Eric Marcos的答案以获取更多详细信息。 
如果您使用的是Django <= 1.6,我build议您使用Kamagatos解决scheme:只需在模型的最后input信号。
对于未来版本的Django(> = 1.7), 推荐的方法是在应用程序的config ()函数中导入你的signals模块:
 my_app/apps.py 
 from django.apps import AppConfig class MyAppConfig(AppConfig): name = 'my_app' def ready(self): import my_app.signals 
 my_app/__init__.py 
 default_app_config = 'my_app.apps.MyAppConfig' 
为了解决你的问题,你只需要在模型定义之后导入signals.py。 就这样。
我也把信号放在signals.py文件中,也有这个加载所有信号的代码片段:
 # import this in url.py file ! import logging from importlib import import_module from django.conf import settings logger = logging.getLogger(__name__) signal_modules = {} for app in settings.INSTALLED_APPS: signals_module = '%s.signals' % app try: logger.debug('loading "%s" ..' % signals_module) signal_modules[app] = import_module(signals_module) except ImportError as e: logger.warning( 'failed to import "%s", reason: %s' % (signals_module, str(e))) 
这是项目,我不知道它是否在应用程序级别上工作。
我猜你正在这样做,所以你的信号被注册了,所以他们被发现的地方。 我只是把我的信号正确地在一个models.py文件。
 在旧的Django版本中,将信号放在__init__.py或者models.py (尽pipe最终模型将会以我的口味为大)。 
 在Django 1.9中,我认为将信号放置在一个apps.py文件中,然后将它们与apps.py一起导入,在加载模型之后将会加载它们。 
apps.py:
 from django.apps import AppConfig class PollsConfig(AppConfig): name = 'polls' def ready(self): from . import signals # NOQA 
 您也可以将signals.py和handlers.py分配到您的模型命名signals中的另一个文件夹中,但是对于我来说这只是工程。 看看放置信号 
 另一种方法是从signals.py导入callback函数,并将它们连接到models.py : 
signals.py
 def pre_save_callback_function(sender, instance, **kwargs): # Do stuff here 
model.py
 # Your imports here from django.db.models.signals import pre_save from yourapp.signals import pre_save_callback_function class YourModel: # Model stuff here pre_save.connect(pre_save_callback_function, sender=YourModel) 
  Ps:在YourModel中导入YourModel会创build一个recursion; 使用sender ,而不是。 
  Ps2:在callback函数中再次保存实例将创build一个recursion。 你可以在.save方法.save一个控制参数来控制它。