Почему 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 как разные модули, которые регистрируют один и тот же сигнал.