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

Django中如何正确发送带PDF附件的邮件?

解决邮件发送与附件异常的问题

嘿,我看了你的代码和遇到的问题,这两个问题其实都是代码里的小细节没处理好,咱们一步步来解决:


第一个问题:收件人没收到邮件,抄送却收到了

问题出在哪?

你在初始化EmailMultiAlternatives的时候,参数传递错了!Django里这个类的cc(抄送)是需要用关键字参数来传递的,你直接把抄送邮箱列表放在了收件人列表后面,这会被当成bcc(密送)参数。另外,你用request.POST.get()来拿表单数据,不如用表单验证后的cleaned_data靠谱——毕竟表单已经通过is_valid()验证了,cleaned_data里的数据是经过校验的,不会有空值或者无效格式。

怎么改?

把收件人和抄送分开,用to=和cc=明确指定,同时换成cleaned_data取数据:

if download_form.is_valid():
    ln_go = get_lang_code(request, request.GET.get('lang'))
    # 换成cleaned_data拿验证后的姓名和邮箱
    name = download_form.cleaned_data['name']
    email = download_form.cleaned_data['email']
    
    # 这里明确用to和cc关键字参数
    msg = EmailMultiAlternatives(
        'Het aangevraagde document',
        f'Geachte {name}, <br/><br />In bijlage sturen wij u het aangevraagde document door. <br /><br />Met vriendelijke groeten, <br /><br /> Het Autralis team',
        'no-reply@autralis.com',
        to=[email],  # 收件人
        cc=['some-email-address@gmail.com']  # 抄送
    )

第二个问题:附件内容错误,显示乱码

问题出在哪?

你给msg.attach()传的是文件路径字符串,但这个方法需要的是文件的二进制内容!所以现在你的附件其实是把"/assets/documents/..."这段文本当成了PDF内容,打开自然是乱码。另外,直接写绝对路径也容易出问题,最好用Django的BASE_DIR来拼接路径,确保不管部署在哪都能找到文件。

怎么改?

先读取PDF的二进制内容,再传给attach():

import os
from django.conf import settings

# 用BASE_DIR拼接正确的文件路径,适配你的目录结构
file_path = os.path.join(settings.BASE_DIR, 'assets', 'documents', f'case_study{ln_go}.pdf')

# 读取文件的二进制数据
with open(file_path, 'rb') as pdf_file:
    pdf_content = pdf_file.read()

# 现在把二进制内容传进去
msg.attach("case_study.pdf", pdf_content, "application/pdf")

完整的修复代码

把上面的修改整合起来,就是这样:

import os
from django.conf import settings
from django.core.mail import EmailMultiAlternatives

if download_form.is_valid():
    ln_go = get_lang_code(request, request.GET.get('lang'))
    # 构建正确的绝对文件路径
    file_path = os.path.join(settings.BASE_DIR, 'assets', 'documents', f'case_study{ln_go}.pdf')
    # 从验证后的表单拿数据
    name = download_form.cleaned_data['name']
    email = download_form.cleaned_data['email']
    
    # 初始化邮件,参数传递正确
    msg = EmailMultiAlternatives(
        'Het aangevraagde document',
        f'Geachte {name}, <br/><br />In bijlage sturen wij u het aangevraagde document door. <br /><br />Met vriendelijke groeten, <br /><br /> Het Autralis team',
        'no-reply@autralis.com',
        to=[email],
        cc=['some-email-address@gmail.com']
    )
    msg.content_subtype = "html"  # 保持HTML格式
    
    # 读取并附加PDF
    with open(file_path, 'rb') as pdf_file:
        pdf_content = pdf_file.read()
    msg.attach("case_study.pdf", pdf_content, "application/pdf")
    
    # 发送邮件,建议加fail_silently=False方便排查错误
    msg.send(fail_silently=False)

额外小贴士

  • 排查邮件发送失败:如果收件人还是没收到,把msg.send()改成msg.send(fail_silently=False),这样如果邮件服务器出错会抛出异常,方便你定位问题;
  • 验证文件存在:可以加一行assert os.path.exists(file_path), f"找不到PDF文件:{file_path}",提前发现文件路径错误;
  • HTML邮件优化:硬编码HTML字符串太麻烦,建议用Django模板来渲染邮件内容,以后改文案或者做国际化都方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:08:13