Сигнал post_save не вызывается

Я уже прочитал все связанные вопросы.

У меня есть два проекта Django, и сигналы работают нормально в одном, но не работают во втором (я просто скопировал код и изменил имена соответственно).

У меня есть приложение заказов с моделью заказа. Приложение включено в настройку INSTALLED_APPS.

У меня есть конфиг приложения в apps.py:

from django.apps import AppConfig


class OrdersConfig(AppConfig):
    name = 'orders'

    def ready(self):
        super(OrdersConfig, self).ready()

        # noinspection PyUnresolvedReferences
        import signals

__init__.py:

default_app_config = 'orders.apps.OrdersConfig'

И, наконец, signal.py:

@receiver(post_save, sender=Order)
def order_save(sender, instance, created, **kwargs):
    print 'Post save'
    if created:
        print 'Created'
        send_email_new_order.delay(settings.MODERATOR_EMAIL, instance.pk)

И сигнал не вызывается. Зачем?

Джанго 1.10.3.

3 ответа

Решение

Когда будет запущен post_save?

Что говорится в документе: В конце метода сохранения.

Что это на самом деле означает: в конце успешного завершения метода сохранения.

Когда сигнал не будет запущен?

  1. Если save метод не может успешно сохранить объект (например, когда IntegrityError происходит)
  2. Когда вы звоните MyModel.objects.update()
  3. Когда вы переопределяете save метод и забудьте вызвать метод суперкласса.
  4. Когда ваш приемник сигнала не был успешно зарегистрирован.

Как зарегистрировать получателя

Проще всего использовать @receiver Декоратор, как вы сделали. Альтернатива заключается в использовании

from django.db.models.signals import pre_save

pre_save.connect(order_save, sender='app_label.MyModel')

Где этот код должен быть размещен?

В настоящее время в руководстве говорится, что

Строго говоря, код обработки сигналов и регистрационный код могут жить где угодно, хотя рекомендуется избегать корневого модуля приложения и модуля его моделей, чтобы минимизировать побочные эффекты импорта кода.

Вероятно, поэтому в этом случае вы создали файл с именем signal.py, поместили в него свой код и пошли на все эти проблемы с классом AppConfig и методом ready. Но, как ни странно, руководство Django 1.6 гласит:

Вы можете разместить код обработки сигнала и регистрационный код где угодно. Однако вам необходимо убедиться, что модуль, в котором он находится, будет импортирован на ранней стадии, чтобы обработка сигналов была зарегистрирована до того, как какие-либо сигналы будут отправлены. Это делает models.py вашего приложения хорошим местом для регистрации обработчиков сигналов.

Так что, если у вас возникли проблемы с регистрацией вашего приемника сигнала, вы можете попробовать вставить свой код в models.py или же views.py и пропустить биты из AppConfig (может быть, даже полностью удалить AppConfig)

Если вы хотите выполнить регистрацию в AppConfig, и у вас возникли проблемы с @reciever и / или импорт, вы можете попробовать

from django.db.models.signals import pre_save
from app_label.signals import my_reciever

def ready(self):
    pre_save.connect(my_reciever, sender='app_label.MyModel')

Как избежать повторов?

Сигнал срабатывает дважды? Убедитесь, что вы зарегистрировали приемник только один раз. Если вы зарегистрируете его в AppConfigоставь это из models.py и наоборот

Вы абсолютно уверены, что правильно signals импортируется? (print('hi, signals here') в модуле?)

Возможно, вы захотите использовать абсолютно квалифицированный импорт (import orders.signals) или относительный (import .signals as signals), тоже.

У вас есть еще одно приложение под названием signals?

Попробуйте относительный импорт в ready метод: from . import signals

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