Why is post_save being raised twice during the save of a Django model?

喜欢而已 提交于 2019-11-29 11:46:19

问题


I am attaching a method to the post_save signal of my Django model. This way I can clear some cached items whenever the model is modified.

The problem I am having is that the signal is being triggered twice when the model is saved. It doesn't necessarily hurt anything (the code will just gracefully error out) but it can't be right.

A quick example, just printing the model to the console (using the dev server):

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)

This is using the stable 1.1.1 release of Django.

Updated Information:

With feedback from everyone's comments, I have modified my question because the issue is now discovering why the post_save is being triggered twice. My guess at the moment is that my models.py code is imported twice and that the post_save is getting connected multiple times.

What would be the best way to figure out why it is being imported/ran twice?


回答1:


Apparently, Python is sensitive to the way you import modules. In my case, it wasn't an issue with any of import code inside my blog application but an issue with the INSTALLED_APPS configuration, which I assume is used by Django to do an initial import.

Inside my blog application I was using imports such as:

from blog.models import *

My settings.py was configured as:

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

The "mysite" prefix was added because I originally had import path issues when deploying the site. Later I fixed this issue (so it acted the same as the development server) by adding multiple paths in my WSGI script.

Removing the "mysite" prefix from the settings.py fixed the issue:

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



回答2:


While looking for the root of this problem, you can use quick workaround to prevent registering signal twice:

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

Source.




回答3:


Here is the ticket about this issue: Django's signal framework may register listeners more than once #3951. It is now fixed in SVN version of Django.

The problem is exactly as You said: Your module which registers signal, is loaded couple of times, in some cases by different import paths, thus each imported modules this way are wrongly interpreted by Django as different modules which registers the same signal.



来源:https://stackoverflow.com/questions/2345400/why-is-post-save-being-raised-twice-during-the-save-of-a-django-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!