代码之家  ›  专栏  ›  技术社区  ›  intelis

向芹菜注册多个任务

  •  0
  • intelis  · 技术社区  · 8 年前

    我正在构建一个简单的helper类,用于用django和芹菜发送电子邮件。

    我的密码

    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)
    

    问题

    当我注册多个任务(例如在上面的代码中)时,不管我调用什么类,都会调用最后一个注册了get的任务。

    例如,如果我这样做:

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

    工人将执行 ReservationDetailsMailer 任务而不是 QuoteRequestMailer 一个。怎样才能用这种方式注册多个任务?

    1 回复  |  直到 8 年前
        1
  •  1
  •   intelis    8 年前

    我可以通过添加一个 name 属性设置为子类。

    例子

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