Сигналы Django @receiver POST_SAVE не работают на PROD (нормально на DEV)

Начинаю сходить с ума ... На dev мои сигналы (для отправки оповещения по почте) работают для всех сохранений (создание + обновление) и удаления. Но на prod, только действие delete посылает письмо. Я не сразу заметил, что сигналы удаления работают, поэтому потратил много времени на поиск проблемы, вызванной брандмауэром (блокирующим исходящую почту).

Post Save

@receiver(post_save, sender=Navette)
def alerte(sender, instance, created, **kwargs):
    ref = instance.ref
    user = instance.user.username

    if created:
        alert(pour=['tintin@gmail.com'],
              sujet=f'Nouvelle navette pour la référence {ref} créé par {user}')
    else:
        alert(pour=['tintin@gmail.com'],
              sujet=f'Mise à jour de la navette pour la référence {ref} par {user}')

Пост Удалить

@receiver(post_delete, sender=Navette)
def alerte(sender, instance, **kwargs):
    ref = instance.ref
    user = instance.user
    alert(pour=['tintin@gmail.com'],
          sujet=f'La navette pour la référence {ref} a été supprimée par {user}')

просто для информации: alert.py

def alert(**kwargs):

    #ref = kwargs.get('ref', 'noref')
    de = kwargs.get('de', 'toto@gmail.com')
    pour = kwargs.get('pour', 'tintin@gmail.com')
    sujet = kwargs.get('sujet', 'Sujet Général')
    contenu = kwargs.get('contenu', 'cf. objet du mail')
    fichier = kwargs.get('fichier', '')

    host = 'smtp.gmail.com'
    port = 465
    user = settings.EMAIL_HOST_USER
    passw = settings.EMAIL_HOST_PASSWORD

    msg = EmailMessage()
    msg['Subject'] = sujet
    msg['From'] = de
    msg['To'] = pour
    msg.set_content('HTML uniquement')

    msg.add_alternative(contenu, subtype='html')

    with smtplib.SMTP_SSL(host, port) as smtp:
        smtp.login(user, passw)
        smtp.send_message(msg)

Как уже было сказано почти везде, я объявил свое приложение не только именем в settings.py : 'navette.apps.NavetteConfig', и зарегистрировал конфиг приложения в его __init__ -> default_app_config = 'navette.apps.ActivityAppConfig' даже если я думал, что слышал, что это больше не нужно на DJANGO 3.

Наконец, вот мой apps.py для этого приложения

from django.apps import AppConfig


class NavetteConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'navette'

    def ready(self):
        import navette.signals

Есть идеи?

Это обходной путь, но если вы действительно сходите с ума от этого, вы можете попробовать использовать сигнал pre_save вместо него. С помощью pre_save вы можете вручную проверить, есть ли у экземпляра id, если нет, то это новый объект.

@receiver(pre_save, sender=Navette)
def alerte(sender, instance, **kwargs):
    ref = instance.ref
    user = instance.user.username

    if not instance.id:
        alert(pour=['tintin@gmail.com'],
              sujet=f'Nouvelle navette pour la référence {ref} créé par {user}')
    else:
        alert(pour=['tintin@gmail.com'],
              sujet=f'Mise à jour de la navette pour la référence {ref} par {user}')

Возможно, что ваша функция-приемник засоряется мусором.

В документации Django по этому поводу сказано следующее:

Обратите внимание, что Django хранит обработчики сигналов как слабые ссылки по по умолчанию, поэтому если ваш обработчик является локальной функцией, он может быть собран в мусор собранным. Чтобы предотвратить это, передайте weak=False при вызове функции сигнала connect().

Попробуйте использовать @receiver(post_save, sender=Navette, weak=False)

Вернуться на верх