Django 4.0无法发送HTML格式密码重置邮件的问题排查
我在Django 4.0中创建了HTML格式的密码重置邮件模板,路径为registration/html_password_reset_email.html。按照资料添加了html_email_template_name参数,但实际只发送文本版模板registration/password_reset_email.html。修改文本模板内容能正常生效,但HTML模板完全没触发。
已尝试的排查操作:
- 将
EMAIL_BACKEND设置为django.core.mail.backends.console.EmailBackend,控制台仅输出文本版内容; - 简化HTML模板为仅
Hello World,依然无法触发; - 修改
email_template_name为registration/test.html,系统仍读取默认路径的文本模板,怀疑PasswordResetView未正确使用传入的参数。
相关配置代码
urls.py
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 ]
settings.py(部分配置)
# 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', ], }, }, ]
模板实际路径:/Users/MYNAME/Documents/repos/begolden/mysite/templates/registration/html_password_reset_email.html
解决方案
解决路由冲突问题
你配置了path('accounts/', include('django.contrib.auth.urls')),这会引入Django默认的密码重置路由(accounts/password_reset/),URL路由匹配是从上到下执行的,可能导致自定义的reset_password/视图未被触发。建议将自定义的reset_password/路由移到include('django.contrib.auth.urls')之前,或者移除accounts/下的默认路由(如果不需要默认认证路由的话),确保自定义的PasswordResetView被正确调用。确认模板文件的正确性
检查html_password_reset_email.html文件名是否完全正确(类Unix系统区分大小写),文件是否存在于指定路径中。可以尝试将HTML模板重命名为和文本模板类似的名称,或者直接替换默认模板路径测试。验证视图参数传递
确保没有其他代码(比如自定义视图、中间件)覆盖了PasswordResetView的参数。Django 4.0的PasswordResetView确实支持html_email_template_name参数,只要视图被正确实例化,就会同时发送文本和HTML格式的邮件。可以尝试在视图中添加打印语句,确认参数是否被正确接收。
内容的提问来源于stack exchange,提问作者user2154589

