为什么在保存Django模型期间会将post_save提升两次?

时间:2010-02-26 22:55:26

标签: python django django-models signals

我将一个方法附加到我的Django模型的post_save信号。这样,无论何时修改模型,我都可以清除一些缓存的项目。

我遇到的问题是在保存模型时信号被触发两次。它不一定会伤害任何东西(代码只会优雅地错误)但它不可能是正确的。

一个简单的例子,只需将模型打印到控制台(使用开发服务器):

from blog.models import Post
from django.db.models import signals

def purge_cache(sender, **kwargs):
    print 'Purging %s' % sender

signals.post_save.connect(purge_cache, sender=Post)

这是使用Django的稳定版1.1.1。

更新信息:

根据每个人的评论反馈,我修改了我的问题,因为现在问题是发现为什么post_save被触发两次。我现在的猜测是我的models.py代码导入了两次,并且post_save多次连接。

找出导入/运行两次的最佳方法是什么?

3 个答案:

答案 0 :(得分:12)

显然,Python is sensitive to the way you import modules。就我而言,我的博客应用程序中的任何导入代码都不是问题,而是INSTALLED_APPS配置的问题,我假设Django使用它进行初始导入。

在我的博客应用程序中,我使用的是导入,例如:

from blog.models import *

我的settings.py配置为:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    ...snip...
    'sorl.thumbnail',
    'mysite.blog',
)

添加了“mysite”前缀,因为我在部署站点时最初遇到了导入路径问题。后来我通过在我的WSGI脚本中添加多个路径来修复此问题(因此它的行为与开发服务器相同)。

从settings.py中删除“mysite”前缀修复了问题:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    ...snip...
    'sorl.thumbnail',
    'blog',
)

答案 1 :(得分:7)

在查找此问题的根源时,您可以使用快速解决方法来防止两次注册信号:

signals.post_save.connect(my_handler, MyModel, dispatch_uid="path.to.this.module")

Source

答案 2 :(得分:0)

以下是有关此问题的故障单:Django's signal framework may register listeners more than once #3951。现在修复了Django的SVN版本。

问题与你所说的完全一样:你的模块注册信号,在某些情况下会被不同的导入路径加载,因此每个导入的模块被Django错误地解释为注册相同信号的不同模块