You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django重置密码API返回成功但邮件未发送问题求助

Django重置密码邮件返回发送成功但未收到的问题排查与解决

问题概述

调用Django应用的重置密码接口,接口返回邮件已发送的确认信息,但实际始终未收到邮件。相关配置与代码如下:

settings.py配置

EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend'
EMAIL_PORT = os.getenv('EMAIL_PORT')
EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS')
EMAIL_HOST = os.getenv('EMAIL_HOST')
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL')

.env配置

EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend"
EMAIL_PORT=465
EMAIL_USE_TLS = True
EMAIL_HOST="ssl0.ovh.net"
EMAIL_HOST_USER=""
EMAIL_HOST_PASSWORD=""
DEFAULT_FROM_EMAIL=EMAIL_HOST_USER

signals.py代码

from django.core.mail import EmailMultiAlternatives, send_mail
from django.dispatch import receiver
from django.template.loader import render_to_string
from django.urls import reverse
from ndgd.settings import EMAIL_HOST_USER
from django_rest_passwordreset.signals import reset_password_token_created
from rest_framework.decorators import api_view, permission_classes

@receiver(reset_password_token_created)
def password_reset_token_created(sender, instance, reset_password_token, *args, **kwargs):
    
    context = {
        'current_user': reset_password_token.user,
        'username': reset_password_token.user.username,
        'email': reset_password_token.user.email,
        'reset_password_url':"{}?token={}".format(
            instance.request.build_absolute_uri(reverse('password_reset:reset-password-confirm')),
            reset_password_token.key)
    }

    # Email
    email_html_message = render_to_string('templates/email/password_reset.email.html', context)
    email_plaintext_message = render_to_string('templates/email/password_reset_email.txt', context)

    ms = EmailMultiAlternatives(
        "Password Reset".format(title = "Nouvelles Donnes"),
        email_plaintext_message,
        EMAIL_HOST_USER,
        [reset_password_token.user.email]
    )

    print(EMAIL_HOST_USER)
    print(reset_password_token.user.email)
    ms.attach_alternative(email_html_message, "text/html")
    ms.send

核心问题与修复方案

1. 邮件发送方法未执行

代码最后一行ms.send只是引用方法对象,并未触发执行,必须添加括号调用方法:

ms.send()  # 补充括号执行发送操作

这是邮件未实际发送的直接原因,信号函数正常执行完毕导致接口返回成功,但发送步骤未触发。

2. 邮箱账号与密码为空

.env中EMAIL_HOST_USER和EMAIL_HOST_PASSWORD为空字符串,必须填写OVH邮箱的正确账号,若开启两步验证则需填写授权码而非登录密码。

3. SMTP端口与加密方式不匹配

OVH的465端口对应SSL加密,而非TLS,修正.env配置:

EMAIL_PORT=465
EMAIL_USE_TLS=False
EMAIL_USE_SSL=True  # 添加SSL加密配置

同时在settings.py中补充对应配置:

EMAIL_USE_SSL = os.getenv('EMAIL_USE_SSL')

4. DEFAULT_FROM_EMAIL配置错误

.env中DEFAULT_FROM_EMAIL=EMAIL_HOST_USER是将字符串"EMAIL_HOST_USER"作为发件人,正确写法应引用环境变量:

DEFAULT_FROM_EMAIL="${EMAIL_HOST_USER}"

5. 模板路径冗余

render_to_string无需前缀templates/,Django会自动在项目templates目录下查找文件,修正路径:

email_html_message = render_to_string('email/password_reset.email.html', context)
email_plaintext_message = render_to_string('email/password_reset_email.txt', context)

6. 标题格式化无效

"Password Reset".format(title = "Nouvelles Donnes")无占位符导致格式化失效,可修改为:

"{} - Password Reset".format("Nouvelles Donnes")

额外排查步骤

  • 检查收件邮箱的垃圾邮件文件夹,确认邮件是否被归类
  • 验证OVH邮箱账号是否能正常登录,SMTP服务是否被启用
  • 开发环境可临时切换至django.core.mail.backends.console.EmailBackend,查看控制台输出的邮件内容是否正常

内容的提问来源于stack exchange,提问作者Dezz H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 07:38:41