使用Celery注册多个任务

时间:2018-06-11 12:55:25

标签: python django celery

我正在构建一个简单的帮助类,用于在Django和Celery中发送电子邮件。

  

我的代码

import logging

from celery import Task
from django.conf import settings
from django.core.mail import send_mail
from render_block import render_block_to_string

from optilimo.celery import app
from reservations.models import Reservation

logger = logging.getLogger(__name__)


class Mailer(Task):
    """
    Build emails from template and send them via Celery.
    Includes some helper functions as well.
    """
    template = None
    from_email = settings.DEFAULT_FROM_EMAIL
    name = 'mailer'
    max_retries = 3

    def build_context(self, ctx):
        return ctx

    def run(self, to_email, ctx, *args, **kwargs):
        ctx = self.build_context(ctx)

        subject = render_block_to_string(self.template, 'subject', ctx)
        plain = render_block_to_string(self.template, 'plain', ctx)
        html = render_block_to_string(self.template, 'html', ctx)

        send_mail(subject, plain, self.from_email,
                  [to_email], html_message=html)
        logger.info('Email sent to {}'.format(to_email))

    def on_success(self, retval, task_id, args, kwargs):
        super(Mailer, self).on_success(retval, task_id, args, kwargs)
        logger.info('Email with task ID {} was successfuly sent.'.format(task_id))

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        super(Mailer, self).on_failure(exc, task_id, args, kwargs, einfo)
        logger.error('Email with task ID {} was failed to send.'.format(task_id))
        logger.error('Error: {}'.format(str(exc)))


class QuoteRequestMailer(Mailer):
    template = 'mails/internal/quote_request.html'


class ReservationDetailsMailer(Mailer):
    template = 'mails/internal/reservation_details.html'

    def build_context(self, ctx):
        reservation = Reservation.objects.first()
        return {'reservation': reservation}


app.tasks.register(QuoteRequestMailer)
app.tasks.register(ReservationDetailsMailer)
  

问题

当我注册多个任务时(例如在上面的代码中),无论我调用哪个类,最后一个注册的任务都会被调用。

例如,如果我这样做:

mail = QuoteRequestMailer()
mail.delay(to_email='demo@mail.com', ctx={'data':'Test'})

工作人员将执行ReservationDetailsMailer任务而不是QuoteRequestMailer任务。如何以这种方式注册多个任务?

1 个答案:

答案 0 :(得分:1)

我能够通过向子类添加name属性来解决它。

  

实施例

class QuoteRequestMailer(Mailer):
    name='mailer.quote_request'  # Important
    template = 'mails/internal/quote_request.html'