Django:如何发送带有嵌入图像的 HTML 电子邮件
Posted
技术标签:
【中文标题】Django:如何发送带有嵌入图像的 HTML 电子邮件【英文标题】:Django: How to send HTML emails with embedded images 【发布时间】:2011-04-16 19:25:58 【问题描述】:如何发送带有嵌入图像的 html 电子邮件? HTML 应该如何链接到图像?图像应作为 MultiPart 电子邮件附件添加?
非常感谢任何示例。
【问题讨论】:
【参考方案1】:我已经尝试了下面的代码并且成功了。
代码:
msg = EmailMessage()
# generic email headers
msg['Subject'] = 'Welcome'
msg['From'] = 'abc@gmail.com'
recipients = ['abc@gmail.com']
# set the plain text body
msg.set_content('This is a plain text body.')
# now create a Content-ID for the image
image_cid = make_msgid(domain='')
# if `domain` argument isn't provided, it will
# use your computer's name
# set an alternative html body
msg.add_alternative("""\
<html>
<body>
<table border='0' cellpadding='1' cellspacing='0' width='800'>
<tbody>
<tr>
<td height='506'>
<table border='0' cellpadding='0' cellspacing='0' width='600'>
<tbody>
<tr>
<td valign='top'>
<img height='190' src="cid:image_cid" width='800' tabindex='0'>
</td>
</tr>
<tr>
<td height='306' valign='top'>
<table cellpadding='0' cellspacing='20' width='800'>
<tbody>
<tr>
<td align='left' height='804' style='font-family:arial,helvetica,sans-serif;font-size:13px' valign='top'>
Hi name,<br><br>
Welcome!
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
""".format(image_cid=image_cid[1:-1],name='ABC'), subtype='html')
# image_cid looks like <long.random.number@xyz.com>
# to use it as the img src, we don't need `<` or `>`
# so we use [1:-1] to strip them off
# now open the image and attach it to the email
with open('/path/image.jpg', 'rb') as img:
# know the Content-Type of the image
maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')
# attach it
msg.get_payload()[1].add_related(img.read(),
maintype=maintype,
subtype=subtype,
cid=image_cid)
server = smtplib.SMTP(host=<hostname>, port=25)
server.starttls()
# send the message via the server.
server.sendmail(msg['From'], recipients, msg.as_string())
server.quit()
【讨论】:
make_msgid(domain='')
函数里面是什么你是如何创建Content-ID
的。并且您没有在代码中添加导入。你能提供更高效的代码吗?【参考方案2】:
http://djangosnippets.org/snippets/285/
你必须使用 MultiPart 和 cid:。发送带有图像的 html 邮件几乎总是一个坏主意。它为您的邮件和 smtp 服务器提供垃圾邮件点...
这里是更好的例子:https://djangosnippets.org/snippets/3001/
【讨论】:
这个好像用的不是django的邮件系统,而是python的smtplib。【参考方案3】:如果您想发送带有图像作为附件的电子邮件(在我的情况下,它是在保存后直接从表单中捕获的图像),您可以使用以下代码作为示例:
#forms.py
from django import forms
from django.core.mail import EmailMessage
from email.mime.image import MIMEImage
class MyForm(forms.Form):
#...
def save(self, *args, **kwargs):
# In next line we save all data from form as usual.
super(MyForm, self).save(*args, **kwargs)
#...
# Your additional post_save login can be here.
#...
# In my case name of field was an "image".
image = self.cleaned_data.get('image', None)
# Then we create an "EmailMessage" object as usual.
msg = EmailMessage(
'Hello',
'Body goes here',
'from@example.com',
['to1@example.com', 'to2@example.com'],
['bcc@example.com'],
reply_to=['another@example.com'],
headers='Message-ID': 'foo',
)
# Then set "html" as default content subtype.
msg.content_subtype = "html"
# If there is an image, let's attach it to message.
if image:
mime_image = MIMEImage(image.read())
mime_image.add_header('Content-ID', '<image>')
msg.attach(mime_image)
# Then we send message.
msg.send()
【讨论】:
【参考方案4】:我实现了 op 要求使用 django 的邮件系统。好处是它将使用 django 设置进行邮件发送(包括用于测试的不同子系统等。我在开发过程中也使用 mailhogs)。它的水平也相当高:
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
message = EmailMultiAlternatives(
subject=subject,
body=body_text,
from_email=settings.DEFAULT_FROM_EMAIL,
to=recipients,
**kwargs
)
message.mixed_subtype = 'related'
message.attach_alternative(body_html, "text/html")
message.attach(logo_data())
message.send(fail_silently=False)
logo_data
是一个附加标志的辅助函数(在这种情况下我想附加的图像):
from email.mime.image import MIMEImage
from django.contrib.staticfiles import finders
@lru_cache()
def logo_data():
with open(finders.find('emails/logo.png'), 'rb') as f:
logo_data = f.read()
logo = MIMEImage(logo_data)
logo.add_header('Content-ID', '<logo>')
return logo
【讨论】:
嘿,谢谢!logo_data
函数确实解释了一个技巧。可惜 Django 的附加函数没有添加可选的标头。
这是发送内嵌图像电子邮件的最短和最佳方式。想特别确认一下使用@lru_cache
是很明智的,但是你忘了在表头加上from functools import lru_cache
。另外,对于这个答案的追随者——这里是 HTML 模板:body_html = """<html><img src="cid:logo" alt="logo image"></html>"""
【参考方案5】:
请记住,django 只为标准 smtplib 提供 wrappers - 我不知道它是否会有所帮助,但请尝试查看以下示例:http://code.activestate.com/recipes/473810-send-an-html-email-with-embedded-image-and-plain-t/
所以我猜你可以使用EmailMessage
的标头值来定义这个'image1' - 消息标头是值的字典,所以只需添加类似'Content-ID': '<image1>'
的内容。
然后使用attach()
将文件附加到您的电子邮件中。之后,您可以使用代码生成这样的 html 消息:
html_content = '<b>Some HTML text</b> and an image: <img src="cid:image1">'
【讨论】:
以上是关于Django:如何发送带有嵌入图像的 HTML 电子邮件的主要内容,如果未能解决你的问题,请参考以下文章