Сигнал сохранения сообщения 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 *

Другие вопросы по тегам