为何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




