我正在构建一个简单的辅助类,用于在 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
任务。如何以这种方式注册多个任务?
我能够通过向子类添加name
属性来解决它。
例
class QuoteRequestMailer(Mailer):
name='mailer.quote_request' # Important
template = 'mails/internal/quote_request.html'