How to customize django rest auth password reset email content/template

梦想与她 提交于 2019-12-02 20:56:05

You need to hook up your own reset password serializer (PASSWORD_RESET_SERIALIZER) with customized save method.

(ref: https://github.com/Tivix/django-rest-auth/blob/v0.6.0/rest_auth/serializers.py#L123)

Unfortunately you need to override the whole save method, due to how the e-mail options are used. We we'll make it a bit more flexible in the next release (0.7.0)

I recently needed to implement the same thing in one of my projects and could not find a thorough answer anywhere.

So I'm leaving my solution here for anyone who needs it in the future.

Expanding on mariodev's suggestion:

1. Create your own PasswordResetSerializer with customized save method.

Base PasswordResetSerializer copied from here: (https://github.com/Tivix/django-rest-auth/blob/v0.6.0/rest_auth/serializers.py#L102)

yourproject_app/serializers.py

from django.contrib.auth.forms import PasswordResetForm
from django.conf import settings
from django.utils.translation import gettext as _
from rest_framework import serializers

###### IMPORT YOUR USER MODEL ######
from .models import ExampleUserModel

class PasswordResetSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password_reset_form_class = PasswordResetForm
    def validate_email(self, value):
        self.reset_form = self.password_reset_form_class(data=self.initial_data)
        if not self.reset_form.is_valid():
            raise serializers.ValidationError(_('Error'))

        ###### FILTER YOUR USER MODEL ######
        if not ExampleUserModel.objects.filter(email=value).exists():

            raise serializers.ValidationError(_('Invalid e-mail address'))
        return value

    def save(self):
        request = self.context.get('request')
        opts = {
            'use_https': request.is_secure(),
            'from_email': getattr(settings, 'DEFAULT_FROM_EMAIL'),

            ###### USE YOUR TEXT FILE ######
            'email_template_name': 'example_message.txt',

            'request': request,
        }
        self.reset_form.save(**opts)

2. Connect custom PasswordResetSerializer to override default

yourproject_app/settings.py

REST_AUTH_SERIALIZERS = {
    'PASSWORD_RESET_SERIALIZER': 
        'yourproject_app.serializers.PasswordResetSerializer',
}

3. Add the path to the directory where your custom email message text file is located to TEMPLATES

yourproject/settings.py

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'yourproject/templates')],
        ...
    }
]

4. Write custom email message (default copied from Django)

yourproject/templates/example_message.txt

{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset 
for your user account at {{ site_name }}.{% endblocktrans %}

{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}

{% trans "Thanks for using our site!" %}

{% blocktrans %}The {{ site_name }} team{% endblocktrans %}

{% endautoescape %}

UPDATE: This solution was written for an older version of django-rest-auth (v0.6.0). As I can tell from the comments, it seems there have been some updates made to the source package that more readily handle custom email templates out-of-box. It is always better to use methods defined in a package rather than overriding them like in my solution. Though once a necessity, it may not be so any longer.

A simple solution is Create over templates directory:

-templates
   -registration
       password_reset_email.html

with content you want. Django rest-auth use django.contrib.auth templates.

Create directory with path as following in your template folder

templates/admin/registration/

Now copy all files in django/contrib/admin/templates/registration/ into this directory you just created. You can find this directory where you have installed django. In linux, it can be find here

/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/registration

You will need root priviliges for accessing this.

Now when you will send email, templates in you just copied in your project will be used.

This link might be helpful. With it I was able to find where the email templates were and how to customize them.

You can find the info at the bottom of the page under Customize the email message http://www.sarahhagstrom.com/2013/09/the-missing-django-allauth-tutorial/#Customize_the_email_message

if you want to use a html email template, an update to Brian's answer would be to add

'html_email_template_name': 'account/email/example_message.html',

just below

###### USE YOUR TEXT FILE ###### 'email_template_name': 'account/email/example_message.txt',

this way you can the email with a html template

You can see why this happens by inspecting the send_mail method of the PasswordResetForm class

class PasswordResetForm(forms.Form):
     email = forms.EmailField(label=_("Email"), max_length=254)

     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`.
              """
             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_message = EmailMultiAlternatives(subject, body, from_email, [to_email])
             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()```
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!