Сигнал 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?
Что говорится в документе: В конце метода сохранения.
Что это на самом деле означает: в конце успешного завершения метода сохранения.
Когда сигнал не будет запущен?
- Если
save
метод не может успешно сохранить объект (например, когдаIntegrityError
происходит) - Когда вы звоните
MyModel.objects.update()
- Когда вы переопределяете
save
метод и забудьте вызвать метод суперкласса. - Когда ваш приемник сигнала не был успешно зарегистрирован.
Как зарегистрировать получателя
Проще всего использовать @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