如何在Python中使用Django发送带附件的异步HTML邮件?

阿辰同学_5387

阿辰同学_5387

2026-10-26

874人浏览

原创

不能直接用send_mail()发附件,因其仅支持纯文本或简单HTML,不支持多部分MIME结构;需用EmailMultiAlternatives添加HTML备选内容和bytes附件,并通过线程、Celery等真正异步发送。

如何在python中使用django发送带附件的异步html邮件?

为什么不能直接用 send_mail() 发附件?

Django 自带的 send_mail() 和 send_mass_mail() 只支持纯文本或简单 HTML 内容,不提供构建多部分 MIME 邮件(如含附件 + HTML 正文)的接口。强行拼接会导致附件损坏、HTML 渲染失败,或被邮箱服务商标记为垃圾邮件。

  • 它底层调用的是 Django.core.mail.EmailMessage,但默认不启用 multipart/related 或 multipart/mixed 结构
  • 附件需通过 attach() 显式添加,且必须在设置 content_subtype='html' 后仍保持正文与附件的 MIME 层级正确
  • 同步发送会阻塞请求线程,尤其当附件较大或 SMTP 延迟高时,Web 请求可能超时

用 EmailMultiAlternatives 构建带附件的 HTML 邮件

EmailMultiAlternatives 是 Django 提供的、专用于多格式邮件(如同时提供 text/plain 和 text/html)并支持附件的类。它比手动构造 MIMEMultipart 更安全,也兼容 Django 的邮件后端配置(如 EMAIL_BACKEND)。

Wechat Article Html
Wechat Article Html

将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。

下载
  • 先实例化 EmailMultiAlternatives,传入主题、空正文(因为 HTML 是备选内容)、发件人和收件人
  • 调用 attach_alternative(html_content, "text/html") 添加 HTML 版本
  • 调用 attach(filename, content, mimetype) 添加附件;content 必须是 bytes(不是 str),常见错误是传入字符串导致乱码或截断
  • 若附件来自文件,推荐用 open(path, "rb").read();若来自内存(如生成的 PDF),确保是 bytes 类型
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
<p>html_content = render_to_string("email/welcome.html", {"name": "Alice"})
msg = EmailMultiAlternatives(
subject="欢迎注册",
body="",  # 纯文本备用内容,可为空
from_email="noreply@example.com",
to=["user@example.com"],
)
msg.attach_alternative(html_content, "text/html")
msg.attach("report.pdf", pdf_bytes, "application/pdf")
msg.send()</p>

如何真正异步发送?别只加个 @asyncio.coroutine

Django 的邮件后端(如 smtp)默认是同步阻塞的。仅用 async def 包裹 msg.send() 没用——它不会自动变成非阻塞调用。

  • 正确做法是把发送逻辑移到线程或进程里:asyncio.to_thread()(Python 3.9+)或 concurrent.futures.ThreadPoolExecutor
  • 如果用 Celery,直接将邮件任务声明为 @shared_task,并在视图中用 send_email_task.delay(...) 触发
  • 注意:异步任务中不能依赖 request 对象或未序列化的 Django model 实例;所有数据需提前序列化(如传 user_id 而非 user 对象)
  • 附件内容不能是文件句柄或临时路径(线程/worker 可能无权限访问),必须是完整 bytes 或 base64 编码后传入

附件过大或 HTML 引用本地资源时的典型问题
  • Gmail 等邮箱会拒绝超过 25MB 的附件;更大的文件应转为下载链接,并在 HTML 中用 @#@#@#@#@#@#@#@#@#@0; 替代
  • HTML 中的 <img src="static/logo.png"> 在邮件客户端里基本不显示——CSS 和图片需内联或转为 CID 引用;推荐用 django-inline-css + premailer 处理样式,图片用 msg.attach() 添加并设 headers={"Content-ID": "<logo>"}</logo>,再在 HTML 中写 <img src="cid:logo">
  • 使用 render_to_string 时,确保模板中不调用数据库查询或耗时函数;否则异步任务本身又变慢了

附件内容是否已转为 bytes,HTML 是否完成内联处理,以及异步执行环境是否隔离了请求上下文——这三点漏掉任一个,都会让邮件发不出或发错。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

HTML速学教程(入门课程)
HTML速学教程(入门课程)

HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python html django

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1811

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4784

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1769

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

28517

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3427

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3427

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1223

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

616

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2663

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习