Почему post save поднимается дважды во время сохранения модели Django?

я прикрепляю метод к сигналу post_save моей модели 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)

Это использование стабильной версии 1.1.1 Django.

Обновленная Информация:

С обратной связью от комментариев всех, я изменил свой вопрос, потому что проблема теперь обнаруживает, почему post_save запускается дважды. На данный момент я думаю, что моя models.py код импортируется дважды и что post_save подключается несколько раз.

каков был бы лучший способ выяснить, почему он импортируется / запускается дважды?

3 ответов


видимо, Python чувствителен к способу импорта модулей. В моем случае это была не проблема с каким-либо кодом импорта внутри моего приложения блога, а проблема с конфигурацией INSTALLED_APPS, которая, как я предполагаю, используется Django для первоначального импорта.

внутри моего приложения для блога я использовал импорт, такой как:

from blog.models import *

мой settings.py был настроен как:

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

префикс "mysite" был добавлен, потому что у меня изначально был проблемы с путем импорта при развертывании сайта. Позже я исправил эту проблему (поэтому она действовала так же, как сервер разработки), добавив несколько путей в мой сценарий WSGI.

удаление префикса" mysite " из settings.py Исправлена ошибка:

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

при поиске корня этой проблемы вы можете использовать быстрый обходной путь, чтобы предотвратить регистрацию сигнала дважды:

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

источник.


вот билет по этому вопросу:структура сигнала Django может регистрировать слушателей более одного раза #3951. Теперь он исправлен в SVN версии Django.

проблема в том, как вы сказали: ваш модуль, который регистрирует сигнал, загружается пару раз, в некоторых случаях разными путями импорта, поэтому каждый импортированный модуль таким образом неправильно интерпретируется Django как разные модули, которые регистрируют один и тот же сигнал.