Does Django password_reset support html HTML templates?

It seems to me that django only supports text messages for reset e-mail passwords. How can I use html templates for this purpose?

+7
source share
6 answers

Here is how you can do an override:

urls.py

url(r'^user/password/reset/$', 'YOUR_APP.views.password_reset', {'post_reset_redirect' : '/#/login?resetemail=true'}, name="password_reset"), 

views.py

 from django.contrib.auth.views import password_reset as django_password_reset from YOUR_APP.forms import CustomPasswordResetForm def password_reset(*args, **kwargs): """ Overriding the Email Password Resert Forms Save to be able to send HTML email """ kwargs['password_reset_form'] = CustomPasswordResetForm return django_password_reset(*args, **kwargs) 

form.py

 from django.contrib.auth.forms import PasswordResetForm from django.contrib.auth.tokens import default_token_generator class CustomPasswordResetForm(PasswordResetForm): """ Overriding the Email Password Resert Forms Save to be able to send HTML email """ def save(self, domain_override=None, email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator, request=None, email_subject_name='registration/password_reset_subject.txt', **kwargs): from django.core.mail import EmailMultiAlternatives from django.utils.html import strip_tags from django.template.loader import render_to_string from django.contrib.sites.models import get_current_site from django.utils.http import int_to_base36 for user in self.users_cache: if not domain_override: current_site = get_current_site(request) site_name = current_site.name domain = current_site.domain else: site_name = domain = domain_override c = { 'email': user.email, 'domain': domain, 'site_name': site_name, 'uid': int_to_base36(user.id), 'user': user, 'token': token_generator.make_token(user), 'protocol': use_https and 'https' or 'http', } render = render_to_string(email_template_name, c) render_subject = render_to_string(email_subject_name, c) msg = EmailMultiAlternatives(render_subject, strip_tags(render), None, [user.email]) msg.attach_alternative(render, "text/html") msg.send() 
+6
source

You can override the save django.contrib.auth.forms.PasswordResetForm method and pass the new form as an argument to the password_reset view.

+5
source

After some trial and error, I found a much simpler way to provide my own reset password pattern in the latest version of Django (1.8).

In project/urls.py add the following imports:

 from django.contrib.auth import views as auth_views from django.core.urlresolvers import reverse_lazy 

And add the following route to your urls before the usual inclusion of the django contrib url route:

 url(r'^accounts/password/reset/$', auth_views.password_reset, { 'post_reset_redirect': reverse_lazy('auth_password_reset_done'), 'html_email_template_name': 'registration/password_reset_html_email.html' }, name='auth_password_reset'), url('^', include('django.contrib.auth.urls')), 

And then in the application’s templates/registration folder, create password_reset_html_email.html with whatever HTML template you want.

The reason this seemed necessary is because of the source for django/contrib/auth/views.py , which has a view function for which the source URL maps to:

 147 def password_reset(request, is_admin_site=False, 148 template_name='registration/password_reset_form.html', 149 email_template_name='registration/password_reset_email.html', 150 subject_template_name='registration/password_reset_subject.txt', 151 password_reset_form=PasswordResetForm, 152 token_generator=default_token_generator, 153 post_reset_redirect=None, 154 from_email=None, 155 current_app=None, 156 extra_context=None, 157 html_email_template_name=None): 158 

The html_email_template_name value html_email_template_name set to None by default, and there seemed to be no way to assign its value other than rewriting this particular route for this case, as I mentioned above.

Hope this helps without having to copy-paste a bunch of almost identical code, for example, some of the other suggested answers - feedback is welcome, of course!

0
source

The study took a lot of time for me, but the solution was pretty trivial. Does not undo any actions with forms or something like that I use Django == 1.8.6, but should work, at least with django 1.7. To enable html-formatted email support in password_reset, all I had to do was change the name of the email template key in the reset function from email_template_name = 'emails / password_reset_email_html.html

to

HTML _email_template_name = 'email / password _reset_email_html.html',

Thus, the reset function will look like that:

 def reset(request): # Wrap the built-in password reset view and pass it the arguments # like the template name, email template name, subject template name # and the url to redirect after the password reset is initiated. return password_reset(request, template_name='profile/reset.html', html_email_template_name='emails/password_reset_email_html.html', subject_template_name='emails/reset_subject.txt', post_reset_redirect=reverse('success')) 
0
source

Based on Cem Kozinoglu's solution, I suggest changing the form and overloading send_mail instead of saving the method as follows:

 class CustomPasswordResetForm(PasswordResetForm): def send_mail(self, subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None): """ Sends 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]) # New line introduce email_message.attach_alternative(body, 'text/html') 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() 
0
source

You can use PasswordResetSerializer http://django-rest-auth.readthedocs.io/en/latest/configuration.html

Then you can override all form parameters:

domain_override subject_template_name email_template_name use_https token_generator FROM_EMAIL request html_email_template_name extra_email_context

in my case, I just redefine 2 details

 class CustomPasswordResetSerializer(PasswordResetSerializer): def get_email_options(self): return { 'domain_override': 'anydomain.com', 'html_email_template_name': 'your_temp/password_reset_email.html', } 
0
source

All Articles