djangodjango-formsdjango-viewsdjango-contribdjango-anymail

django built-in password_reset change connection from send_email


In my application i'm using the built-in auth views. I'm also using a postmark connection using django-anymail for some user email notifications.

Example: 

email_backend = get_connection('anymail.backends.postmark.EmailBackend')
   mail = EmailMessage(
   subject=subject,
   body=message,
   to=[settings.DEFAULT_FROM_EMAIL],
   connection=email_backend
   )

I want to change the connection i'm sending email with in PasswordResetView. Is there any way i can give a keyword argument in the PasswordResetView.as_view() the same way i'm giving html_email_template_name='...' or success_url='...'? or do i have to rewrite PasswordResetView?


Solution

  • You don't have to change the PasswordResetView, but you will have to create a custom PasswordResetForm that you can then pass as a keyword argument to PasswordResetView.as_view().

    If you look at the source code of PasswordResetView, you will see that it doesn't actually send the email itself. The email sending is done as part of PasswordResetForm.save(), which calls PasswordResetForm.send_mail()

    You could subclass PasswordResetForm and overwrite .send_mail() to use your custom email backend:

    from django.contrib.auth.forms import PasswordResetForm
    
    class PostmarkPasswordResetForm(PasswordResetForm):
        def send_mail(self, subject_template_name, email_template_name,
                      context, from_email, to_email, html_email_template_name=None):
            """
            Send a django.core.mail.EmailMultiAlternatives to `to_email` using
            `anymail.backends.postmark.EmailBackend`.
            """
            subject = loader.render_to_string(subject_template_name, context)
            # Email subject *must not* contain newlines
            subject = ''.join(subject.splitlines())
            body = loader.render_to_string(email_template_name, context)
    
            email_backend = get_connection('anymail.backends.postmark.EmailBackend')
    
            email_message = EmailMultiAlternatives(subject, body, from_email, [to_email], connection=email_backend)
            if html_email_template_name is not None:
                html_email = loader.render_to_string(html_email_template_name, context)
                email_message.attach_alternative(html_email, 'text/html')
    
            email_message.send()