【问题标题】:Django signals not triggered when a model object is created创建模型对象时未触发 Django 信号
【发布时间】:2021-09-24 07:21:21
【问题描述】:

当管理员发布从 Django 管理员创建的博文时,我正在使用 Django 信号触发任务(使用 django celery 包向订阅者发送大量电子邮件)。但是没有触发信号。我在未打印的信号中有一个打印语句,即在创建新博客后未接收到信号。

我的应用是这样设置的。

我的博客模型:

class BlogPost(models.Model):

    author = models.CharField(max_length=64, default='Admin')    
    image = models.ImageField(blank=True, null=True)
    title = models.CharField(max_length=255)
    .................../

我的任务文件

from django.core.mail import send_mail

from travel_crm.settings import EMAIL_HOST_USER

    @shared_task
    def send_mails(self,*args, **kwargs):
    
        subscribers = self.kwargs['subscribers']
        blog = self.kwargs['blog']
        for abc in subscribers:
            emailad = abc.email
            send_mail('New Blog Post ', f" Checkout our new blog with title {blog.title} ",
                      EMAIL_HOST_USER, [emailad],
                      fail_silently=False)

我的信号.py 文件

from .tasks import send_mails
from apps.blogs.models import BlogPost,Subscribers
from django.db.models.signals import post_save
from django.dispatch import receiver


    @receiver(post_save, sender=BlogPost)
    def email_task(sender, instance, created, **kwargs):
        print(123456789)
        if created:
            print(123456789)
            subscribers = Subscribers.objects.all()
            blog = BlogPost.objects.latest('date_created')
            print(blog)
            # task = send_mails(subscribers, blog)
            # task.delay()
            send_mails.delay(subscribers,blog)

我的初始化文件

from __future__ import absolute_import, unicode_literals
from apps.blogs.celery_files.celery import app as celery_app
__all__ = ('celery_app',)

【问题讨论】:

  • 您的代码示例不起作用。您提供的方法没有类 (def send_mail) 和模型中的 sn-ps,它们甚至缺少您在其他 sn-ps (date_created) 中使用的字段。你确定这个问题是特定于邮件的 - 换句话说,你能确认 celery 正常工作吗?
  • 我在 Blogpost 中使用了.....因为有很多字段我不需要在这里写所以...

标签: django django-rest-framework django-celery django-signals


【解决方案1】:

您必须在某处导入您的signals.py 才能注册它,django 文档建议将其导入应用程序的apps.py 文件内的ready() 方法中,如下所示:

from django.apps import AppConfig


class BlogsConfig(AppConfig):
    name = 'blogs'

    def ready(self):
        import blogs.celery_files.signals

https://docs.djangoproject.com/en/3.2/topics/signals/#connecting-receiver-functions

【讨论】:

  • 我这样做了,但我仍然没有得到 123456789 的打印结果。这是什么问题??
【解决方案2】:

检查您的我的任务文件文件。您是否共享了整个文件?

你写道:

from django.core.mail import send_mail

from travel_crm.settings import EMAIL_HOST_USER

    @shared_task
    def send_mails(self,*args, **kwargs):
    
        subscribers = self.kwargs['subscribers']
        blog = self.kwargs['blog']
        for abc in subscribers:
            emailad = abc.email
            send_mail('New Blog Post ', f" Checkout our new blog with title {blog.title} ",
                      EMAIL_HOST_USER, [emailad],
                      fail_silently=False)

如果这是整个文件,则有多个问题需要修复:

  1. 使用 @shared_task 装饰器而不使用相应的导入 from celery import shared_task
  2. 错误的意图 - 没有理由打算使用该功能
  3. 在类外使用 self 参数

你在signals.py中有同样的意图问题。

【讨论】:

  • 每个文件都没有缩进。我不知道它如何在这里显示缩进。我已经导入了 shared_task(否则它不起作用)我没有在这里发布,这是我的错误。主要问题是信号代码首先没有运行,因为打印没有显示。
猜你喜欢
  • 2021-02-07
  • 2012-07-31
  • 2011-09-21
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2018-02-17
  • 2017-04-13
相关资源
最近更新 更多