15👍
Adding my findings for django version 2.0 as I found the rest of the answers to this question to be out-of-date.
With 2.0, the proper way of adding a URL to your urls.py file is by using path()
:
from django.urls import path
from django.contrib.auth import views as auth_views
path('accounts/password_reset/', auth_views.PasswordResetView.as_view(
html_email_template_name='registration/password_reset_html_email.html'
)),
The next code snippet to highlight here is the .as_view()
function. Django 2.0 implements auth views as classes. You can read more about this in the Authentication Views documentation
You then “convert” the class to a view using `.as_view() and you are able to pass in any class attributes defined in the source code as named parameters.
Passing in html_email_template_name (which defaults to None) automatically sends an html email.
You can access the source code for PasswordResetView by following this python path: django.contrib.auth.views
Here you can see the other class attributes you can pass into PasswordResetView and the other auth views. This is super helpful for passing extra_context into your django templates as well.
11👍
[cross-posted from Does Django password_reset support html email templates? ]
After some amount of trial and error, I discovered a much, much more terse way to supply a custom templated password reset email in the latest version of Django (1.8).
In your project/urls.py
, add these imports:
from django.contrib.auth import views as auth_views
from django.core.urlresolvers import reverse_lazy
And add the following route in your urlpatterns before the usual django contrib auth url route inclusion:
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 your app’s templates/registration
folder, create the password_reset_html_email.html
with whatever HTML template you want.
The reason this seemed necessary lay in the source for django/contrib/auth/views.py
, which has the view function the original URL route is mapped 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
is set to None
as default, and there didn’t seem to be a way to assign its value, aside from rewriting this specific route for this case as I mentioned above.
Hopefully this helps without needing to copy-paste a bunch of nearly-identical code like some of the other answers suggested – feedback is welcome, of course!
- Django's {{ csrf_token }} is outputting the token value only, without the hidden input markup
- Django ALLOWED_HOSTS with ELB HealthCheck
- Django render_to_string() ignores {% csrf_token %}
- How does use_for_related_fields work in Django?
10👍
The default helper views for django authentication cannot send multi-part (HTML) emails because the underlying send_mail
method does not support HTML emails yet.
This will be fixed in the next release, by adding a html_message
flag.
The easiest way to fix this is to create your own custom password reset form, and use EmailMultiAlternatives
to send your message, thus allowing your HTML to render correctly in the email client.
You can use the existing form, and make your changes:
class HTMLPasswordResetForm(forms.Form):
email = forms.EmailField(label=_("Email"), max_length=254)
def save(self, domain_override=None,
subject_template_name='registration/password_reset_subject.txt',
email_template_name='registration/password_reset_email.html',
use_https=False, token_generator=default_token_generator,
from_email=None, request=None):
"""
Generates a one-use only link for resetting password and sends to the
user.
"""
# from django.core.mail import send_mail
from django.core.mail import EmailMultiAlternatives
UserModel = get_user_model()
email = self.cleaned_data["email"]
active_users = UserModel._default_manager.filter(
email__iexact=email, is_active=True)
for user in active_users:
# Make sure that no email is sent to a user that actually has
# a password marked as unusable
if not user.has_usable_password():
continue
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': urlsafe_base64_encode(force_bytes(user.pk)),
'user': user,
'token': token_generator.make_token(user),
'protocol': 'https' if use_https else 'http',
}
subject = loader.render_to_string(subject_template_name, c)
# Email subject *must not* contain newlines
subject = ''.join(subject.splitlines())
email = loader.render_to_string(email_template_name, c)
msg = EmailMessage(subject, email, from_email, [user.email])
msg.content_subtype = "html" # Main content is now text/html
msg.send()
#send_mail(subject, email, from_email, [user.email])
Once you have done that, change your password_reset
method call and pass in your new form class:
password_reset(request, password_reset_form=HTMLPasswordResetForm)
- How does this Man-In-The-Middle attack work?
- TypeError: create_superuser() missing 1 required positional argument: 'profile_picture'
- In django, is there a way to directly annotate a query with a related object in single query?
- Django widget override template
7👍
Django 2
You can create a custom template in the templates
folder: templates/registration/password_reset_email.html
and add it to your main urls.py
.
# add this import
from django.contrib.auth import views as auth_views
...
# add this path
path('accounts/password_reset/', auth_views.PasswordResetView.as_view(
html_email_template_name='registration/password_reset_email.html'
)),
# just before this line (to take priority over the default one)
path('accounts/', include('django.contrib.auth.urls')),
- How to clear all session variables without getting logged out
- How can I make a fixture out of QuerySet in django?
- Registered models do not show up in admin
- Changing password in Django Admin
- Django database synchronization for an offline usage
3👍
For django2.2 use this thing to add a custom email template in the password reset email template
In urls.py file add these lines
urlpatterns = [
path('password-reset',
auth_views.PasswordResetView.as_view(
template_name='accounts/password_reset.html',
html_email_template_name="accounts/email_reset_template.html",
email_template_name='accounts/password_reset_email.html',
subject_template_name="accounts/password_reset_subject.txt",
),
name="password_reset"),
path('password-reset/done',
auth_views.PasswordResetDoneView.as_view(
template_name='accounts/password_reset_done.html'),
name="password_reset_done"),
path('password-reset-complete/',
auth_views.PasswordResetCompleteView.as_view(
template_name='accounts/password_reset_complete.html'),
name="password_reset_complete"),
path('password-reset-confirm/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(
template_name='accounts/password_reset_confirm.html'),
name="password_reset_confirm"),
#Add more urls you want
]
After adding above lines you can omit the email_template name from ‘password_reset’ if you provide the html template name but to use template in the email sent via email you need the html template now choose your own html template
from different webiste you want and place that file inside the same folders where all password reset files are there.
Now important part is to add the link inside your custom html template to add this you need to add the following lines to your custom html template like this:
<a href="{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}" style=".."> Reset Password </a>
and you can add the below line anywhere in the html template according to your needs
{% load i18n %}
{% autoescape off %} You're receiving this e-mail because you requested a password reset for your Xandar account. {% trans "Thanks for using our site!" %} {% blocktrans %}The {{ site_name }} team{% endblocktrans %} {% endautoescape %}
If you still having any doubt then let me know
This definitely works and I have used this in my project.
1👍
Have you tried to edit this template?
registration/password_reset_email.html
You can add a password_reset_email.html file to your templates/registration folder in your project, then add the relevant sections / HTML to get a nice template.
The default template is empty.
- Changing password in Django Admin
- How does this Man-In-The-Middle attack work?
- How can I automatically let syncdb add a column (no full migration needed)
- Django. Error message for login form
1👍
I solved this by changing the parameter of password_reset function in django.contrib.auth views file. By default html_email_template_name is None.
If you direct it to ‘registration/password_reset_email.html’ file, its sending emails with proper html.
def password_reset(request,
template_name='registration/password_reset_form.html',
email_template_name='registration/password_reset_email.html',
subject_template_name='registration/password_reset_subject.txt',
password_reset_form=PasswordResetForm,
token_generator=default_token_generator,
post_reset_redirect=None,
from_email=None,
extra_context=None,
html_email_template_name='registration/password_reset_email.html',
extra_email_context=None):
- How can I make SSE with Python (Django)?
- Change default Django REST Framework home page title
- Is there a way to render a html page without view model?
- How to unit test methods inside django's class based views?
- Django. Error message for login form
0👍
You have to overide the default html. To do that goto you django istallation folder in libs/site-packages/django
and copy password_reset_email.html
from django templates and paste it in [templates]/registration/password_reset_email.html
. Then define your CSS and edit the the default html and if your HTML code shows up in body turn off django template manager auto escaping but it’s not recommanded.
0👍
You can do the following.
Add both to the password_reset:
html_email_template_name='YOUR TEMPLATE PATH',
email_template_name='YOUR TEMPLATE PATH'
It worked for me (Django 1.11)
- ProgrammingError: relation "django_session" does not exist
- What does it mean for an object to be unscriptable?
0👍
The simplest (and honestly only way) to force the email to be sent as HTML was to override the form_valid
method.
views.py:
class MyPasswordResetView(PasswordResetView):
# forcing to use HTML email template (param: html_email_template_name)
def form_valid(self, form):
opts = {
'use_https': self.request.is_secure(),
'token_generator': self.token_generator,
'from_email': self.from_email,
'email_template_name': self.email_template_name,
'subject_template_name': self.subject_template_name,
'request': self.request,
'html_email_template_name': 'registration/password_reset_email.html',
'extra_email_context': self.extra_email_context,
}
form.save(**opts)
return HttpResponseRedirect(self.get_success_url())
urls.py
path('password_reset/', myapp.MyPasswordResetView.as_view(), name='password_reset'),
- Accessing django project in LAN systems
- How to create custom groups in django from group
- Registered models do not show up in admin
- Installing django 1.5(development version) in virtualenv
0👍
1) Add a password_reset_email.html file to your templates/registration folder in your project “myApp”.
2) Move ‘django.contrib.admin’ below ‘myApp’ in your INSTALLED_APPS.
https://github.com/macropin/django-registration/issues/50#issuecomment-142637807
Not the best solution, but it worked for me!