Сигнал Django m2m_changed никогда не вызывается - программирование
Подтвердить что ты не робот

Сигнал Django m2m_changed никогда не вызывается

Я не могу понять, почему мой сигнал m2m_changed не запускается.

Вот код:

models.py

class Badge(TimeStampable, Expirable, Deactivable,
            SafeDeleteModel):
    _safedelete_policy = HARD_DELETE

    owner = models.ForeignKey(settings.AUTH_USER_MODEL,
                              blank=True, null=True,
                              on_delete=models.PROTECT)
    restaurants = models.ManyToManyField(Restaurant)
    identifier = models.CharField(max_length=2048)

    objects = SafeDeleteManager.from_queryset(BadgeQuerySet)()

signals.py

from django.db.models.signals import m2m_changed
from django.dispatch import receiver

from .models import Badge

@receiver(m2m_changed, sender=Badge.restaurants.through)
def my_callback(sender, **kwargs):
    print("M2M has been changed!")

apps.py (этот пост рекомендовал изменить этот файл)

from django.apps import AppConfig

class BadgesConfig(AppConfig):
    name = 'badges'

    def ready(self):
        import badges.signals

При переходе в оболочку:

  • m2m_changed.receivers возвращает пустой список (он не работает, и сигнал никогда не может быть получен)

Я нашел подобный пост, но не нашел ответа на него.

Почему сигнал m2m_changed не работает?

РЕДАКТИРОВАТЬ

Когда вы открываете оболочку и импортируете badges.signals, она работает. Это означает, что проблема заключается в apps.py:

In [1]: from django.db.models.signals import m2m_changed

In [2]: m2m_changed.receivers
Out[2]: []

In [3]: import badges.signals

In [4]: m2m_changed.receivers
Out[4]:
[((4551224720, 4520068792),
  <weakref at 0x10f4da5e8; to 'function' at 0x10f462d90 (check_uniqueness)>)]
4b9b3361

Ответ 1

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

Собственно, чтобы правильно зарегистрировать приложение, у меня есть два метода:

метод 1

INSTALLED_APPS = ['badges',...]

и объявление в __init__.py: default_app_config = 'badges.apps.BadgesConfig'

метод 2

INSTALLED_APPS = ['badges.apps.BadgesConfig']

виноват

Я использовал INSTALLED_APPS = ['badges',...] не объявляя ничего в __init__.py

Я думаю, возможно, Django может отображать предупреждение, когда он замечает, что apps.py находится в приложении папки, но никогда не используется.