Django 信号 @receiver POST_SAVE 在 PROD 上不起作用(在 DEV 上正常)

问题描述 投票:0回答:2

快疯了…… 在开发中,我的信号(用于通过邮件发送警报)适用于所有保存(创建+更新)和删除。 但是在产品上,只有删除操作才会发送电子邮件。我没有立即注意到删除信号正在起作用,因此我花了很多时间寻找由防火墙引起的问题(阻止电子邮件传出)。

保存后

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

    if created:
        alert(pour=['[email protected]'],
              sujet=f'Nouvelle navette pour la référence {ref} créé par {user}')
    else:
        alert(pour=['[email protected]'],
              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=['[email protected]'],
          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', '[email protected]')
    pour = kwargs.get('pour', '[email protected]')
    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'
中注册了应用程序配置,即使我认为 Ik 听说它不再需要了姜戈 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

有什么想法吗?

编辑

navette.views

@login_required
def NavetteCreateView(request):
    form = NavetteDetailForm(request.POST)
    if request.method == 'POST':
        form = NavetteDetailForm(request.POST)
        if form.is_valid():
            form.save()
            navette_ref = form.cleaned_data.get('ref')
            logr.debug(f'{navette_ref} - enregistrée')
            messages.success(
                request, f'La navette {navette_ref} a bien 
        été créée.')
            return redirect('/navettes')
    else:
        form = NavetteDetailForm()

    context = {'form': form, 'title': 'Nouvelle Navette'}
    return render(request, 'navette/navette_form.html', 
context)

我检查了form_valid -> True

python django signals production
2个回答
4
投票

您的接收器函数可能正在被垃圾收集。

Django 文档在这个主题上这样说:

另请注意,Django 将信号处理程序存储为弱引用 默认,所以如果你的处理程序是本地函数,它可能是垃圾 集。为了防止这种情况,当你调用信号的时候传递weak=False 连接()。

尝试使用

@receiver(post_save, sender=Navette, weak=False)


0
投票

这是一种解决方法,但如果您真的对此感到抓狂,您可以尝试使用

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=['[email protected]'],
              sujet=f'Nouvelle navette pour la référence {ref} créé par {user}')
    else:
        alert(pour=['[email protected]'],
              sujet=f'Mise à jour de la navette pour la référence {ref} par {user}')
© www.soinside.com 2019 - 2024. All rights reserved.