Почему post_save вызывается дважды во время сохранения модели Django? - PullRequest
15 голосов
/ 27 февраля 2010

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

Используется стабильная версия Django 1.1.1.

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

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

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

Ответы [ 3 ]

12 голосов
/ 27 февраля 2010

Очевидно, 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',
)
7 голосов
/ 27 февраля 2010

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

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

Источник .

0 голосов
/ 27 февраля 2010

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

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

...