代码之家  ›  专栏  ›  技术社区  ›  cethegeek

Win2003上Outlook 2003中的Django EmailMultiAlternatives和HTML电子邮件显示

  •  2
  • cethegeek  · 技术社区  · 16 年前

    我正在使用django.core.mail.emailMultiAlternatives从我的django应用程序发送电子邮件,以确保邮件在电子邮件客户端不支持HTML时降级为文本。

    以下是我的发送电子邮件方法:

    def send_email(self, from_address, to_list, subject, msg_text, msg_html):
            subject=subject.replace('\r','').replace('\n',' ')
            self.msg = EmailMultiAlternatives(subject, msg_text, from_address, to_list)
            self.msg.attach_alternative(msg_html, "text/html")
            self.msg.content_subtype = "html"
            self.msg.send()
    

    它与gmail、hotmail和许多其他电子邮件客户机一起工作得很好—显示HTML内容没有问题。但它不会在运行在Win2003上的Outlook2003中显示HTML内容,只显示文本版本。

    如果我在emailmultivatives调用中强制使用HTML,即使用msg _html instead of msg 像这样的文本:

    self.msg = EmailMultiAlternatives(subject, msg_html, from_address, to_list)
    

    然后,它在所有客户机中都能正常工作;但这意味着,对于不支持HTML的客户机或(更可能)已禁用对HTML支持的客户机,没有文本回退。

    我认为值得一提的是,电子邮件是在运行在Mac OS X上的Django应用程序上生成的(只是为了防止它与操作系统之间的行终止符差异有关)。

    我明白了 people using other languages 对前景也有类似的问题…

    我想知道是否有人知道为什么Outlook的行为会有所不同,以及是否有简单的修复可以应用到我的代码中?

    1 回复  |  直到 16 年前
        1
  •  5
  •   moberley    16 年前

    我没有可用的Outlook安装来测试这个,所以我想知道函数中第五行的原因。

    self.msg.content_subtype = "html"

    我不太了解多部分电子邮件的内部结构,但是在我的系统中,这一行导致消息的两个部分都具有文本/html的内容类型。去掉它会产生一条消息,第一部分是“content-type:text/plain”,第二部分是“content-type:text/html”。

    在任何情况下,关于Java问题的答案之一提到将字符集更改为ISO-859-1。我想你应该可以用django.core.mail来完成。

    emailMessage类(emailMultiAlternatives从中继承)有一个名为“encoding”的属性,该属性设置要使用的字符集。默认情况下,它是无的,所以使用默认的utf-8字符集(除非在设置中被重写)。

    换句话说,在问题中列出的函数的发送行之前添加如下内容:

    self.msg.content_subtype = "iso-8859-1"

    不幸的是,这只会更改第一部分指定的编码(上面函数中的msg_文本)。附加可选内容的函数似乎不使用编码属性。我不确定这是正确的方法,但我将emailmultialtiables子类化,以覆盖相关的功能,它似乎可以正常工作。

    class EmailMultiAlternativesWithEncoding(EmailMultiAlternatives):
        def _create_attachment(self, filename, content, mimetype=None):
            """
            Converts the filename, content, mimetype triple into a MIME attachment
            object. Use self.encoding when handling text attachments.
            """
            if mimetype is None:
                mimetype, _ = mimetypes.guess_type(filename)
                if mimetype is None:
                    mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
            basetype, subtype = mimetype.split('/', 1)
            if basetype == 'text':
                encoding = self.encoding or settings.DEFAULT_CHARSET
                attachment = SafeMIMEText(smart_str(content,
                    settings.DEFAULT_CHARSET), subtype, encoding)
                # original text being replaced above (not last argument)
                # attachment = SafeMIMEText(smart_str(content,
                #     settings.DEFAULT_CHARSET), subtype, settings.DEFAULT_CHARSET)
            else:
                # Encode non-text attachments with base64.
                attachment = MIMEBase(basetype, subtype)
                attachment.set_payload(content)
                Encoders.encode_base64(attachment)
            if filename:
                attachment.add_header('Content-Disposition', 'attachment',
                                      filename=filename)
            return attachment

    我不确定“smart”str(content,settings.default_charset)部分是否也应该引用“encoding”而不是“settings.default_charset”,但这是消息正文处理文本(django.core.mail.emailmessage.message)。

    正如我所说,我没有outlook,所以我不能实际测试outlook方面,但它似乎将两部分的字符集都更改为i so-8859-1。