如何禁用Django中PasswordResetView的自动发送重置密码邮件功能
我在Django中自定义了CustomPasswordResetView,相关代码如下:
views.py 代码
class CustomPasswordResetView(PasswordResetView): template_name = 'users/password_reset_form.html' success_url = reverse_lazy('password_reset') def form_valid(self, form): email = form.cleaned_data['email'] # 检查提供的邮箱是否存在活跃用户 try: user = User.objects.get(email=email, is_active=True) except User.DoesNotExist: messages.success(self.request, 'ok.') return super().form_valid(form) # 用户不存在或未激活时返回默认行为 # 生成uidb64和token uidb64 = urlsafe_base64_encode(force_bytes(user.pk)) token = default_token_generator.make_token(user) print(email, uidb64, token) messages.success(self.request, 'ok.') return super().form_valid(form)
urls.py 代码
urlpatterns = [ path('password_reset/', CustomPasswordResetView.as_view(), name='password_reset'), path('reset/<uidb64>/<token>/', CustomPasswordResetConfirmView.as_view(), name='password_reset_confirm'), path('reset/done/', CustomPasswordResetCompleteView.as_view(), name='password_reset_complete'), ]
settings.py 代码
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' EMAIL_HOST = '*****' EMAIL_PORT = 465 EMAIL_USE_SSL = True EMAIL_HOST_USER = '******' EMAIL_HOST_PASSWORD = '*****' AUTH_USER_MODEL = 'users.User' ACCOUNT_EMAIL_CONFIRMATION_MODEL = 'users_custom.CustomEmailConfirmation'
当我在users/password_reset_form.html页面输入邮箱申请重置密码时,Django会自动发送邮件,控制台中显示的邮件内容如下:
You're receiving this email because you requested a password reset for your user account at http://127.0.0.1:8000.
Please go to the following page and choose a new password:
http://http://127.0.0.1:8000/users/reset/MQ/c0exppa87e20490eb2e3c11513cad273efc4cc/
Your username, in case you’ve forgotten: a@a.com
Thanks for using our site!
The http://127.0.0.1:8000 team
请问如何禁用Django的这种自动发送重置密码邮件的行为?
解决方案
你可以通过以下两种简单方法禁用自动发邮件:
方法一:重写send_password_reset_email方法
在你的CustomPasswordResetView中添加一个空实现的send_password_reset_email方法,父类PasswordResetView的form_valid逻辑最终会调用这个方法发送邮件,空实现会直接跳过发邮件步骤:
class CustomPasswordResetView(PasswordResetView): template_name = 'users/password_reset_form.html' success_url = reverse_lazy('password_reset') def send_password_reset_email(self, email): # 空方法,不执行任何发邮件操作 pass def form_valid(self, form): # 原有逻辑保持不变 email = form.cleaned_data['email'] try: user = User.objects.get(email=email, is_active=True) except User.DoesNotExist: messages.success(self.request, 'ok.') return super().form_valid(form) uidb64 = urlsafe_base64_encode(force_bytes(user.pk)) token = default_token_generator.make_token(user) print(email, uidb64, token) messages.success(self.request, 'ok.') return super().form_valid(form)
方法二:不调用父类的form_valid
如果你不需要父类form_valid的其他逻辑,可以直接在自定义的form_valid中处理完业务后,直接重定向到成功页面,跳过父类的发邮件流程:
class CustomPasswordResetView(PasswordResetView): template_name = 'users/password_reset_form.html' success_url = reverse_lazy('password_reset') def form_valid(self, form): email = form.cleaned_data['email'] try: user = User.objects.get(email=email, is_active=True) except User.DoesNotExist: messages.success(self.request, 'ok.') return redirect(self.success_url) uidb64 = urlsafe_base64_encode(force_bytes(user.pk)) token = default_token_generator.make_token(user) print(email, uidb64, token) messages.success(self.request, 'ok.') # 直接重定向,不调用super,避免触发父类的发邮件逻辑 return redirect(self.success_url)
注意:第二种方法要确保你已经处理了所有需要的逻辑(比如用户不存在的情况),因为跳过父类的form_valid后,也不会执行父类里的其他校验或操作。
内容的提问来源于stack exchange,提问作者hossein ghodrati

