代码之家  ›  专栏  ›  技术社区  ›  Lance McNearney

为什么在保存django模型的过程中,post-save被提升了两倍?

  •  15
  • Lance McNearney  · 技术社区  · 15 年前

    我正在将一个方法附加到Django模型的后保存信号。这样,每当修改模型时,我就可以清除一些缓存项。

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

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

    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版本。

    更新信息:

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

    找出它为什么被导入/运行两次的最好方法是什么?

    3 回复  |  直到 7 年前
        1
  •  12
  •   Community CDub    7 年前

    显然地, Python is sensitive to the way you import modules . 在我的例子中,这不是我博客应用程序中任何导入代码的问题,而是安装的_-apps配置的问题,我假设Django使用它进行初始导入。

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

    from blog.models import *
    

    my 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',
    )
    
        2
  •  7
  •   Dmitry Shevchenko    15 年前

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

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

    Source .

        3
  •  0
  •   Dawid    15 年前

    这是关于这个问题的罚单: Django's signal framework may register listeners more than once #3951 .它现在在Django的SVN版本中被修复。

    问题就如您所说:您的模块(用于注册信号)被加载了几次,在某些情况下是通过不同的导入路径加载的,因此Django错误地将每个导入的模块解释为注册相同信号的不同模块。