First of all I know this question has been answered previously here which use a third-party package django-celery-email, but I am trying to figure out how to do do such job without relaying on any third-party library.
So I need to send password reset email asynchronously with Celery.
My forms.py
file look like this:
from django import forms
from accounts.tasks import send_mail
from django.contrib.auth.forms import PasswordResetForm as PasswordResetFormCore
class PasswordResetForm(PasswordResetFormCore):
email = forms.EmailField(max_length=254, widget=forms.TextInput(
attrs={
'class': 'form-control',
'id': 'email',
'placeholder': 'Email'
}
))
def send_mail(self, subject_template_name, email_template_name,
context, from_email, to_email, html_email_template_name=None):
"""
This method is inherating Django's core `send_mail` method from `PasswordResetForm` class
"""
super().send_mail(subject_template_name, email_template_name,
context, from_email, to_email, html_email_template_name)
I am trying to send mail via Celery from send_mail
method of PasswordResetForm
class. I mean calling super().send_mail(...)
with Celery. I also have a send_mail
function in my Celery's tasks.py
file, where I am trying to pass super().send_mail
method as an argument to call it from there.
Right now my tasks.py
file looks something like this:
from __future__ import absolute_import, unicode_literals
@shared_task
def send_mail():
pass
I am using RabbitMQ
as message broker alongside with Celery
Ok I have come across with a working solution for this. Here is my solution.
I have changed forms.py
like following
from django import forms
from accounts.tasks import send_mail
from django.contrib.auth.forms import PasswordResetForm as PasswordResetFormCore
class PasswordResetForm(PasswordResetFormCore):
email = forms.EmailField(max_length=254, widget=forms.TextInput(
attrs={
'class': 'form-control',
'id': 'email',
'placeholder': 'Email'
}
))
def send_mail(self, subject_template_name, email_template_name, context,
from_email, to_email, html_email_template_name=None):
context['user'] = context['user'].id
send_mail.delay(subject_template_name=subject_template_name,
email_template_name=email_template_name,
context=context, from_email=from_email, to_email=to_email,
html_email_template_name=html_email_template_name)
And the changed tasks.py
is like following
from __future__ import absolute_import, unicode_literals
from accounts.models import User
from django.contrib.auth.forms import PasswordResetForm
@shared_task
def send_mail(subject_template_name, email_template_name, context,
from_email, to_email, html_email_template_name):
context['user'] = User.objects.get(pk=context['user'])
PasswordResetForm.send_mail(
None,
subject_template_name,
email_template_name,
context,
from_email,
to_email,
html_email_template_name
)