Django 5中PasswordResetView无法发送Gmail SMTP邮件问题
解决Django PasswordResetView无法发送邮件的问题
以下是针对你的场景的排查和解决思路:
1. 检查自定义用户模型的字段配置
PasswordResetView依赖用户模型的EMAIL_FIELD来获取收件人邮箱,确保你的CustomUser模型正确配置了该字段:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from django.db import models class CustomUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True, verbose_name='邮箱') # 其他自定义字段... USERNAME_FIELD = 'email' # 设置邮箱为登录用户名 EMAIL_FIELD = 'email' # 明确指定用于发送邮件的字段 REQUIRED_FIELDS = [] # 其他必要的管理器和方法...
如果未指定EMAIL_FIELD,视图可能无法正确定位用户的邮箱地址,导致无收件人可发送。
2. 规范视图配置(避免函数包装类视图)
你当前用函数包装类视图的写法可能导致上下文传递异常,直接使用类视图更可靠:
# views.py from django.contrib.auth import views as auth_views from django.urls import reverse_lazy class CustomPasswordResetView(auth_views.PasswordResetView): template_name = "accounts/password-reset.html" success_url = reverse_lazy("accounts:password-reset-done") extra_email_context = {"site_name": "你的站点名称"} # 按需添加上下文
对应的URL配置:
# urls.py path("password-reset/", views.CustomPasswordResetView.as_view(), name="password-reset"),
3. 自定义密码重置表单(如果需要)
如果你的自定义用户模型邮箱字段名不是email,或者需要自定义用户查找逻辑,创建自定义表单:
from django.contrib.auth.forms import PasswordResetForm as BasePasswordResetForm class CustomPasswordResetForm(BasePasswordResetForm): def get_users(self, email): # 根据自定义用户模型的EMAIL_FIELD查找活跃用户 return self.user_model.objects.filter( **{f"{self.user_model.EMAIL_FIELD}__iexact": email}, is_active=True )
然后在视图中指定该表单:
class CustomPasswordResetView(auth_views.PasswordResetView): # ... 其他配置 form_class = CustomPasswordResetForm
4. 开启邮件日志排查错误
在settings.py中添加日志配置,查看邮件发送的详细过程:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': {'class': 'logging.StreamHandler'}, }, 'loggers': { 'django.core.mail': { 'handlers': ['console'], 'level': 'DEBUG', }, }, }
运行项目后提交密码重置请求,查看控制台输出,确认是否有用户查找失败、邮件发送异常等日志信息。
5. 验证Gmail配置细节
虽然Shell能发送邮件,但仍需确认:
- 如果你的Gmail账号开启了两步验证,必须使用应用专用密码,而非普通密码(低安全性应用访问不适用于开启2FA的账号)。
- 检查Gmail的「已发送邮件」和「垃圾邮件」文件夹,确认邮件是否被归类或发送成功但未被注意到。
6. 排查其他干扰因素
- 确认提交密码重置的邮箱对应的用户是
is_active=True状态(PasswordResetView仅向活跃用户发送邮件)。 - 暂时禁用自定义中间件和信号,测试是否有代码拦截了邮件发送流程。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

