Я создаю простой вспомогательный класс для отправки электронных писем в 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)
Задача
Когда я регистрирую более одной задачи (например, в коде выше)), последнее зарегистрированное задание get вызывается независимо от того, какой класс я вызываю.
Например, если я выполню:
mail = QuoteRequestMailer()
mail.delay(to_email='demo@mail.com', ctx={'data':'Test'})
Рабочий выполнит задачу ReservationDetailsMailer
, а не QuoteRequestMailer
один.Как я могу зарегистрировать несколько задач таким образом?