You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何EmailMultiAlternatives无法发送带PDF附件的邮件?

排查邮件未送达问题的可能原因及修复方案

咱们来一步步拆解你代码里可能导致带PDF附件的邮件无法送达的问题,同时给出对应的修复建议:

1. 相对路径导致PDF文件找不到

你直接使用'nds.pdf'作为文件名,这是相对路径,如果代码运行时的当前工作目录和PDF生成的目录不一致,attach_file()就会找不到文件,直接导致邮件发送失败。

修复方案:使用绝对路径

借助os模块生成绝对路径,确保能准确定位到生成的PDF文件:

import os

# 生成绝对路径
pdf_path = os.path.join(os.getcwd(), 'nds.pdf')

# 生成PDF时使用绝对路径
HTML(string=t, base_url=base_path).write_pdf(
    pdf_path, presentational_hints=True
)

# 附件也用绝对路径
email.attach_file(pdf_path)

如果是Django项目,更推荐将PDF生成到MEDIA_ROOT目录下,避免权限或路径混乱问题。

2. 缺失Django邮件SMTP配置

Django发送邮件依赖settings.py中的SMTP配置,如果你没配置或者配置错误,邮件根本无法通过SMTP服务器发送出去。尤其是你用Gmail作为发件人,需要特殊配置:

修复方案:完善settings.py的邮件配置

settings.py中添加以下配置(注意Gmail的特殊要求):

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'eliz.moon5@gmail.com'
# 如果你开启了两步验证,这里需要用【应用专用密码】,而不是你的账户密码
EMAIL_HOST_PASSWORD = 'your_app_specific_password'

注意:Gmail默认禁止普通密码登录SMTP,你需要开启「不太安全的应用访问」(不推荐),或者开启两步验证后生成应用专用密码(推荐)。

3. 未添加异常捕获,无法定位具体错误

你的代码没有任何异常处理逻辑,哪怕是SMTP认证失败、PDF生成失败、网络超时等问题,你都无法知道具体原因,排查起来就像无头苍蝇。

修复方案:添加异常捕获

捕获常见的邮件发送异常,方便精准排查问题:

from django.core.mail.exceptions import MailSendError

try:
    # PDF生成代码
    pdf_path = os.path.join(os.getcwd(), 'nds.pdf')
    HTML(string=t, base_url=base_path).write_pdf(pdf_path, presentational_hints=True)
    
    # 邮件发送代码
    email = EmailMultiAlternatives(
        'Subject here', 'Here is the message.', 'eliz.moon5@gmail.com', ['elizzz.ekzo@mail.ru']
    )
    email.attach_file(pdf_path)
    email.send()
    print("邮件发送成功!")
except MailSendError as e:
    print(f"邮件发送错误:{e}")
except FileNotFoundError:
    print("找不到生成的PDF文件!")
except Exception as e:
    print(f"意外错误:{e}")

4. PDF生成可能失败

HTML转PDF的过程可能因为模板语法错误、依赖库缺失(比如weasyprint)、资源加载失败(比如模板中的静态资源)导致PDF没有生成,后续附件自然无法添加。

修复方案:验证PDF生成结果

在生成PDF后,检查文件是否存在且大小正常:

pdf_path = os.path.join(os.getcwd(), 'nds.pdf')
HTML(string=t, base_url=base_path).write_pdf(pdf_path, presentational_hints=True)

# 检查PDF是否生成成功
if not os.path.exists(pdf_path) or os.path.getsize(pdf_path) == 0:
    print("PDF生成失败,请检查模板或依赖库!")
    # 这里可以添加终止流程的逻辑

5. 邮箱服务器限制或格式问题

  • 确认收件人邮箱格式正确(elizzz.ekzo@mail.ru看起来是对的,但可以再核对一遍)
  • 检查发件人邮箱是否被收件人服务器列入黑名单
  • Gmail有每日发送数量限制,如果发送过多可能会被临时限制

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

火山引擎 最新活动