Сигнал сохранения сообщения Django вызывается дважды, несмотря на uid
Я зарегистрировал свой сигнал с помощью обратного вызова, используя @receiver
декоратор
@receiver(post_save, sender=User, dispatch_uid='ARandomUniqueString')
def do_callback(sender, **kwargs):
Я поставил from app.signals import *
код в __init__.py
и я вижу, что он импортируется дважды, и я не думаю, что есть хороший способ исправить это, возможно, из-за installed apps
в settings.py
, Я не могу понять, почему, несмотря на использование dispatch_uid
и modelInstance.save
будучи вызванным только один раз, он все еще работает do_callback
дважды. Какие-либо предложения?
4 ответа
Итак, я перенес импорт в views.py
(или же models.py
и пока он импортировался только один раз, его вызывали дважды.
Проблема заключалась в том, что post_save
сигнал вызывался, когда объект был создан, а также сохранен. Я понятия не имею, почему, поэтому я добавил обходной путь, который теперь работает
created = False
#Workaround to signal being emitted twice on create and save
if 'created' in kwargs:
if kwargs['created']:
created=True
#If signal is from object creation, return
if created:
return
Редактировать:
post_save
звонили дважды, потому что я использовал .create(...)
что эквивалентно __init__(...)
а также .save()
,
Заключение
dispatch_uid
работает и делает единый импорт - все еще хорошая практика.
У меня была такая же проблема с сигналами post_save и post_delete. Кажется, что объект сеанса и объект LogEntry были сохранены, а также создали несколько сигналов, несмотря на установку dispatch_uid.
Что сработало для меня:
from django.contrib.admin.models import LogEntry
from django.contrib.sessions.models import Session
....
if sender in [LogEntry, Session]:
return
else:
# do your thing here
Я только что столкнулся с той же проблемой. У меня есть приемник, который делает что-то важное, что должно быть сделано только один раз для каждого нового создания экземпляра модели в Django. Итак, я использовал post_save
сигнал, но это вызывалось дважды для создания каждого нового экземпляра модели, который я делал как Profile.objects.create(...)
, Решением этой проблемы является created
флаг, который идет с kwargs
, Вот как вы можете использовать этот флаг, чтобы убедиться, что ваше запланированное действие выполнено только один раз:
@receiver(post_save, sender=Profile)
def publish_auction(sender, **kwargs):
if kwargs['created']:
kwargs['instance'].send_email_confirmation()
Я попробовал dispatch_uid
предложение от Django Docs. Это не сработало, но код, который я вставил выше, работает.
Я поставил
from app.signals import *
код в__init__.py
Вы не должны ничего класть в __init__.py
файл.
Если вы удалите это из __init__.py
и добавить его в нижней части вашего models.py
, это должно решить вашу проблему.
Вы также должны избегать "слепого" импорта from foo import *