问题描述
在我的网络应用程序中,我偶尔会使用这样的可重复使用的邮件应用程序发送电子邮件:
In my web application I send emails occasionally using a reusable mailer application like this:
user - self.user
subject = ("My subject")
from = "me@mydomain.com"
message = render_to_string("welcomeEmail/welcome.eml", {
"user" : user,
})
send_mail(subject, message, from, [email], priority="high" )
我想发送一封带有嵌入图像的电子邮件,所以我尝试在邮件客户端中制作邮件,查看源代码,并将其放入我的模板 (welcome.eml),但我一直无法获得它在发送时在邮件客户端中正确呈现.
I want to send an email with embedded images in it, so I tried making the mail in a mail client, viewing the source, and putting it into my template (welcome.eml), but I've been unable to get it to render correctly in mail clients when its sent.
有谁知道一种简单的方法可以让我创建带有内嵌图像的 mime 编码邮件模板,这些模板在我发送时会正确呈现?
Does anyone know of an easy way for me to create mime encoded mail templates with inline images that will render correctly when I send them?
推荐答案
更新
非常感谢 Saqib Ali 在我回复将近 5 年后重新提出这个老问题.
Many thanks to Saqib Ali for resurrecting this old question nearly 5 years after my reply.
我当时给出的指示不再有效.我怀疑在此期间 Django 有一些改进,这意味着 send_mail()
强制执行纯文本.无论您在内容中放入什么内容,它都将始终以纯文本形式传送.
The instructions I gave at the time no longer work. I suspect there have been some improvements to Django in the intervening years which mean that send_mail()
enforces plain text. No matter what you put in the content, it will always be delivered as plain text.
最新的 Django 文档 解释了 send_mail()
实际上只是创建 django.core.mail.EmailMessage
类的一个实例,然后在其上调用 send()
的便利实例.EmailMessage
有关于 body 参数的注释,它解释了我们现在在 2014 年看到的结果:
The most recent Django documentation explains that send_mail()
is really just a convenience for creating an instance of the django.core.mail.EmailMessage
class, and then calling send()
on that instance. EmailMessage
has this note for the body parameter, which explains the results we're seeing now in 2014:
body:正文.这应该是纯文本消息.
...稍后在文档中...
... somewhat later in the docs ...
默认情况下,EmailMessage 中 body 参数的 MIME 类型是text/plain".最好不要管它.
By default, the MIME type of the body parameter in an EmailMessage is "text/plain". It is good practice to leave this alone.
足够公平(我承认我没有花时间调查 2009 年指令为何有效——我确实在 2009 年对其进行了测试——或者当它发生变化时).Django 确实提供了文档django.core.mail.EmailMultiAlternatives
类,使发送同一消息的纯文本和 HTML 表示更容易.
Fair enough (I confess I haven't taken the time to investigate why the 2009 instructions worked - I did test them back in 2009 - or when it changed). Django does provide, and document, a django.core.mail.EmailMultiAlternatives
class to make it easier for sending a plain text and HTML representation of the same message.
这个问题的情况略有不同.我们不寻求附加替代方案本身,而是将相关部分附加到其中一个替代方案.在 HTML 版本中(无论是否有纯文本版本都没有关系),我们想要嵌入图像数据部分.不是内容的替代视图,而是在 HTML 正文中引用的相关内容.
The case in this question is slightly different. We're not seeking to append an alternative per se, but to append related parts to one of the alternatives. Within the HTML version (and it doesn't matter if you have or omit the plain text version), we want to embed an image data part. Not an alternative view of the content, but related content that is referenced in the HTML body.
仍然可以发送嵌入的图像,但我没有看到使用 send_mail
的直接方法.是时候放弃便利功能并直接实例化EmailMessage
.
Sending an embedded image is still possible, but I don't see a straightforward way to do it using send_mail
. It's time to dispense with the convenience function and to instantiate an EmailMessage
directly.
这是对上一个示例的更新:
Here's an update to the previous example:
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 部分.
To send an e-mail with embedded images, use python's built-in email module to build up the MIME parts.
应该做到以下几点:
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(子类型普通)附加到替代部分.然后将图像附加到相关的根.
In reality, you'll probably want to send the HTML along with a plain-text alternative. In that case, use MIMEMultipart to create the "related" mimetype container as the root. Then create another MIMEMultipart with the subtype "alternative", and attach both a MIMEText (subtype html) and a MIMEText (subtype plain) to the alternative part. Then attach the image to the related root.
这篇关于创建一个带有图像的 MIME 电子邮件模板,用 python/django 发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!