将我的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
一个控制参数来控制它。