更新
非常感谢Saqib Ali在我回复近 5 年后再次提出这个老问题。
我当时给出的指示不再有效。我怀疑在这几年中对 Django 进行了一些改进,这意味着它send_mail()
强制执行纯文本。无论您在内容中添加什么内容,它都将始终以纯文本形式提供。
最新的Django 文档解释说,这send_mail()
实际上只是为了方便地创建django.core.mail.EmailMessage
类的实例,然后调用send()
该实例。EmailMessage
有这个关于 body 参数的注释,它解释了我们现在在 2014 年看到的结果:
正文:正文。这应该是纯文本消息。
...在文档中稍晚一些...
默认情况下,EmailMessage 中 body 参数的 MIME 类型为“text/plain”。最好不要管它。
很公平(我承认我没有花时间调查为什么 2009 年的指令有效——我确实在 2009 年对它们进行了测试——或者什么时候改变了)。Django 确实提供了documentdjango.core.mail.EmailMultiAlternatives
类,以便更轻松地发送相同消息的纯文本和 HTML 表示。
这个问题的情况略有不同。我们并不寻求附加替代方案本身,而是将相关部分附加到替代方案之一。在 HTML 版本中(无论是否有纯文本版本都没有关系),我们想要嵌入图像数据部分。不是内容的替代视图,而是HTML 正文中引用的相关内容。
仍然可以发送嵌入图像,但我没有看到使用send_mail
. 是时候放弃便利功能并EmailMessage
直接实例化一个了。
这是对上一个示例的更新:
from django.core.mail import EmailMessage
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Load the image you want to send as bytes
img_data = open('logo.jpg', 'rb').read()
# Create a "related" message container that will hold the HTML
# message and the image. These are "related" (not "alternative")
# because they are different, unique parts of the HTML message,
# not alternative (html vs. plain text) views of the same content.
html_part = MIMEMultipart(_subtype='related')
# Create the body with HTML. Note that the image, since it is inline, is
# referenced with the URL cid:myimage... you should take care to make
# "myimage" unique
body = MIMEText('<p>Hello <img src="cid:myimage" /></p>', _subtype='html')
html_part.attach(body)
# Now create the MIME container for the image
img = MIMEImage(img_data, 'jpeg')
img.add_header('Content-Id', '<myimage>') # angle brackets are important
img.add_header("Content-Disposition", "inline", filename="myimage") # David Hess recommended this edit
html_part.attach(img)
# Configure and send an EmailMessage
# Note we are passing None for the body (the 2nd parameter). You could pass plain text
# to create an alternative part for this message
msg = EmailMessage('Subject Line', None, 'foo@bar.com', ['bar@foo.com'])
msg.attach(html_part) # Attach the raw MIMEBase descendant. This is a public method on EmailMessage
msg.send()
2009年的原始回复:
要发送带有嵌入图像的电子邮件,请使用 python 的内置电子邮件模块来构建 MIME 部分。
以下应该做到这一点:
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Load the image you want to send at bytes
img_data = open('logo.jpg', 'rb').read()
# Create a "related" message container that will hold the HTML
# message and the image
msg = MIMEMultipart(_subtype='related')
# Create the body with HTML. Note that the image, since it is inline, is
# referenced with the URL cid:myimage... you should take care to make
# "myimage" unique
body = MIMEText('<p>Hello <img src="cid:myimage" /></p>', _subtype='html')
msg.attach(body)
# Now create the MIME container for the image
img = MIMEImage(img_data, 'jpeg')
img.add_header('Content-Id', '<myimage>') # angle brackets are important
msg.attach(img)
send_mail(subject, msg.as_string(), from, [to], priority="high")
实际上,您可能希望将 HTML 与纯文本选项一起发送。在这种情况下,使用 MIMEMultipart 创建“相关”mimetype 容器作为根。然后使用子类型“alternative”创建另一个 MIMEMultipart,并将 MIMEText(子类型 html)和 MIMEText(子类型 plain)附加到替代部分。然后将图像附加到相关的根。