【问题标题】:creating a MIME email template with images to send with python / django创建一个带有图像的 MIME 电子邮件模板以使用 python / django 发送
【发布时间】:2010-12-10 15:01:04
【问题描述】:

在我的网络应用程序中,我偶尔会使用这样的可重用邮件应用程序发送电子邮件:

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),但我一直无法获得它在发送时在邮件客户端中正确呈现。

有没有人知道一种简单的方法来创建带有内联图像的 mime 编码邮件模板,当我发送它们时会正确呈现?

【问题讨论】:

    标签: python django email mime


    【解决方案1】:

    更新

    非常感谢Saqib Ali 在我回复近 5 年后再次提出这个老问题。

    我当时给出的指示不再有效。我怀疑在这几年中对 Django 进行了一些改进,这意味着 send_mail() 强制执行纯文本。无论您在内容中添加什么内容,都将始终以纯文本形式提供。

    最新的Django documentation 解释说send_mail() 实际上只是为了方便创建django.core.mail.EmailMessage 类的实例,然后在该实例上调用send()EmailMessage 有这个关于 body 参数的注释,它解释了我们现在在 2014 年看到的结果:

    body:正文。这应该是纯文本消息。

    ...稍后在文档中...

    默认情况下,EmailMessage 中正文参数的 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)附加到替代部分。然后将图像附加到相关的根目录。

    【讨论】:

    【解决方案2】:

    我在使用 Jarret 在 Django 1.10 上的方法时遇到了问题 - 以各种方式附加 MIME 数据时出现 MIME 和编码错误。

    这是一个用于电子邮件的简单多部分事务模板,其中嵌入了适用于 django 1.10 的 coupon_image 文件对象:

    from django.core.mail import EmailMultiAlternatives
    from email.mime.image import MIMEImage
    
    def send_mail(coupon_image):
        params = {'foo':'bar'} # create a template context
        text_body = render_to_string('coupon_email.txt', params)
        html_body = render_to_string('coupon_email.html', params)
        img_data = coupon_image.read() #should be a file object, or ImageField
        img = MIMEImage(img_data)
        img.add_header('Content-ID', '<coupon_image>')
        img.add_header('Content-Disposition', 'inline', filename="coupon_image")
    
        email = EmailMultiAlternatives(
            subject="Here's your coupon!",
            body=text_body,
            from_email='noreply@example.com',
            to=['someone@example.com',]
        )
    
        email.attach_alternative(html_body, "text/html")
        email.mixed_subtype = 'related'
        email.attach(img)
    
        email.send(fail_silently=False)
    

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2011-02-18
      • 2018-03-09
      • 2015-11-11
      • 1970-01-01
      相关资源
      最近更新 更多