Почему 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 подключается несколько раз.
Что было бы лучшим способом выяснить, почему он импортируется/запускается дважды?
Ответы
Ответ 1
По-видимому, 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 script.
Удаление префикса "mysite" из settings.py исправлено:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
...snip...
'sorl.thumbnail',
'blog',
)
Ответ 2
При поиске корня этой проблемы вы можете использовать быстрое обходное решение для предотвращения регистрации сигнала дважды:
signals.post_save.connect(my_handler, MyModel, dispatch_uid="path.to.this.module")
Источник.
Ответ 3
Вот билет по этой проблеме: Структура сигнала Django может регистрировать слушателей более одного раза # 3951. Теперь он исправлен в версии SVN Django.
Проблема в том, как вы сказали: ваш модуль, который регистрирует сигнал, загружается пару раз, в некоторых случаях разными путями импорта, поэтому каждый импортированный модуль таким образом неправильно интерпретируется Django как разные модули, которые регистрируют один и тот же сигнал.