Reputation: 49
I created an html-styled version of a password reset email to be set with django 4.0 located at 'registration/html_password_reset_email.html'. From other stackoverflows, I learned I needed to add the html_email_template_name parameter for the html version of the email to be sent. However, even with the below code, it is just the text version of the file that is being sent ('registration/password_reset_email.html'). It is definitely fining the registration/password_reset_email.html file, because edits I make to it are successfully emailed, but I can't get it to send the html version. Hints on what I'm doing wrong?
from django.contrib import admin
from django.urls import include, path
from django.contrib.auth import views as auth_views
from django.views.generic.base import RedirectView
from django.urls import reverse
from . import views
urlpatterns = [
path('', views.homeview, name="homeview"),
path('dashboard/', include('dashboard.urls')),
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path("register/", views.register_request, name="register"),
path('reset_password/', auth_views.PasswordResetView.as_view(
template_name='registration/password_reset_form.html',
html_email_template_name='registration/html_password_reset_email.html',
email_template_name='registration/password_reset_email.html',
), name="reset_password"), # Submit email form
path('reset_password_sent/', auth_views.PasswordResetDoneView.as_view(), name="password_reset_done"), # Email sent success message
path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name="password_reset_confirm"), # Link to password reset form in email
path('reset_password_complete/', auth_views.PasswordResetCompleteView.as_view(), name="password_reset_complete"), # Password successfully changed message
]
This is part of my settings.py file
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Take environment variables from .env file
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
# Application definition
INSTALLED_APPS = [
'dashboard.apps.DashboardConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
'mysite',
'users',
'corsheaders',
]
AUTH_USER_MODEL = 'users.User'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
BASE_DIR resolves to: /Users/MYNAME/Documents/repos/begolden/mysite/templates and my template files are at: /Users/MYNAME/Documents/repos/begolden/mysite/templates/registration/html_password_reset_email.html
I tried setting EMAIL_BACKEND to django.core.mail.backends.console.EmailBackend and the text version in registration/password_reset_email.html (not the html version) prints out to console. I also tried changing the html file to just say "Hello World", in case the original html was malformed. The text registration/password_reset_email.html still prints to console (not the html file location).
I think it isn't actually using the file locations I'm providing, because when I change the email_template_name like below, it doesn't read the new text 'registration/test.html'. It still reads the text at the default location 'registration/password_reset_email.html '. I find this confusing though, because it IS finding my custom text at 'registration/password_reset_email.html', which seems to imply that my folder structure is correct but PasswordResetView just isn't using the argument names I am giving it??
path('password_reset/', auth_views.PasswordResetView.as_view(
html_email_template_name='registration/html_password_reset_email.html',
email_template_name='registration/test.html'
), name="password_result"),
Upvotes: 1
Views: 879
Reputation: 34942
You named your URL reset_password
, while the name used by Django is password_reset
. You have to use the same name, as it will be called by Django with reverse('reset_password')
:
urlpatterns = [
...,
path('accounts/', include('django.contrib.auth.urls')),
...,
path('reset_password/', auth_views.PasswordResetView.as_view(
template_name='registration/password_reset_form.html',
html_email_template_name='registration/html_password_reset_email.html',
email_template_name='registration/password_reset_email.html',
), name="password_reset"), # <-
...,
]
Also, beware to keep this URL pattern after path('accounts/', include('django.contrib.auth.urls'))
, as the URL name will clash and the last one has the precedence.
When naming URL patterns, choose names that are unlikely to clash with other applications' choice of names. If you call your URL pattern comment and another application does the same thing, the URL that reverse() finds depends on whichever pattern is last in your project's urlpatterns list.
Upvotes: 1