Django EmailMultiAlternatives and HTML e-mail display in Outlook 2003 on Win2003

I'm using django.core.mail.EmailMultiAlternatives when sending e-mails from my django app in an attempt to make sure that the message downgrades to text if the e-mail client doesn't support HTML.

Here is my send_email method:

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"

It works great with Gmail, Hotmail and many other e-mail clients - displaying the HTML content without a problem. But it will not display the HTML content in Outlook 2003 running on Win2003 - just the text version.

If I forcefully put the HTML in the EmailMultiAlternatives call, i.e. use msg_html instead of msg_text like so:

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

then it works correctly in all clients; but that means that there is no text fallback for clients that don't support HTML or (more likely) that have disabled support for it.

I think it is worth mentioning that the e-mail is being generated on a django app running on Mac OS X (just in case it has to do with line terminator differences between the OSes).

I see that people using other languages have had similar problems with outlook...

I wonder if anyone has any idea of WHY outlook would behave differently and if there is simple fix that can be applied in my code?

Asked by: Caroline219 | Posted: 06-12-2021

Answer 1

I don't have an Outlook installation available to test this, so I'm wondering about the reason for the fifth line in your function.

self.msg.content_subtype = "html"

I don't know much about multipart email internals, but on my system that line causes both parts of the message have a content-type of text/html. Leaving it out produces a message with "Content-Type: text/plain" on the first part and "Content-Type: text/html" on the second.

In any case, one of the answers to the question about Java mentions changing the character set to iso-8859-1. I think you should be able to do that with django.core.mail.

The EmailMessage class (from which EmailMultiAlternatives inherits) has an attribute named "encoding" which sets the charset to use. By default it's None so the default charset of utf-8 (unless overridden in settings) is used instead.

In other words, add something like the following before the send line in the function listed in the question:

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

Unfortunately, that will only change the encoding specified on the first part (msg_text in the function above). The function that attaches the alternative content doesn't seem to use the encoding attribute. I'm not sure it's the correct approach but I subclassed EmailMultiAlternatives to override the relevant function and it seemed to work okay.

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)
            # Encode non-text attachments with base64.
            attachment = MIMEBase(basetype, subtype)
        if filename:
            attachment.add_header('Content-Disposition', 'attachment',
        return attachment

I'm not sure if the "smart_str(content, settings.DEFAULT_CHARSET)" part should also reference "encoding" rather than "settings.DEFAULT_CHARSET" but that's the message body handling text is written (django.core.mail.EmailMessage.message).

As I said, I don't have Outlook so I can't actually test the Outlook aspect but it does seem to change the charset to iso-8859-1 for both parts.

Answered by: John878 | Posted: 07-01-2022

Similar questions

python - Django EmailMultiAlternatives with Embadded Image in HTML

I am trying to send email with HTML and embadded image. Email sending working fine and its also attaching the image in email but its not showing the image in HTML (inline). I used Content:ID in view and cid in template but no success :(. I explore so many forms and apply solutions but in vain please help!. Here is my code: html_content = render_to_string('newsletters/newsletter_template.html', vars) text_co...

python - Django EmailMultiAlternatives sending to multiple "to" addresses

Is there a way in Django EmailMultiAlternatives that you can send to multiple "to" addresses, without having to send it again? Have tried separating the email int the tuple by commas, but only the first recipient receives the emails.

Python/Django EmailMultiAlternatives send multiple emails

i want to send multiple emails in a view. what i need is, that view sends the responcse back and send emails in the background. when i run return EmailMultiAlternatives(subject, t, sender, recipients, bcc=bcc).send() the view does not send the response until it sends...

python + django+ EmailMultiAlternatives Template' object has no attribute 'encode

I am sending an email by following method: EmailMultiAlternatives() When the send() method is called; I get error in somewhere base class. lib/email/ 'Template' object has no attribute 'encode' Exception Location: C:\Python27\lib\email\ in encode_7or8bit, line 73 Python Executable: C:\Python27\python...

python - Celery Error with EmailMultiAlternatives

I have a wrapper around EmailMultiAlternatives to make the interface a little bit cleaner (taken nearly verbatim from here): class Email(object): ''' Wrapper around the Django core's EmailMultiAlternatives that makes it simpler to render txt and html templates. ''' ...

python - Add reply to address to django EmailMultiAlternatives

I am trying to add a "reply to" email while using django's EmailMultiAlternatives format. The documentation demonstrates who to do it with EmailMessage class but doesn't show how to do it when using EmailMultiAlternatives.

python - Email django from using EmailMultiAlternatives

I'm trying to send a mail using Django with EmailMultiAlternatives. It works well but in "from" says "info" Is it posible to say my name for example? How can I do this? Here is my code: subject, from_email, to = 'Afiliations', '', '' text_content = 'Afiliation is working.' t = loader.get_template('emails/afiliados.html') c = Context({ 'order': ...

python - Django EmailMultiAlternatives not attaching pdf

I have the following code in Python to send an email with an attached pdf. result_url = '%s%s?analysis_id=%s' % ( constants.HOST_URL, reverse('results'), pdf_filename = ''.join(['report', str(analysis_id), '.pdf']) utils.convert_to_pdf(result_url, pdf_filename) and here is my utils.convert_to_pdf. def convert_to_pdf(url, filename): com...

python - Django emailmultialternatives include round bracket in from email

I'm trying to send email in django using EmailMultiAlternatives. Here is my code: email_msg = EmailMultiAlternatives(subject,text_content,"Abc (ABC) <>",['']) email_msg.send() the email is sent out fine but the contents inside the bracket in my from email were missing. So when I received the email, from email is like this "Abc <>" i...

python - Adding headers to Django EmailMultiAlternatives

In Django EmailMultiAlternatives documentation there is nothing about how to add headers like "format" or "Reply-To" in EmailMultiAlternatives. It took a while for me to figure it out and I am sending this post to help others with saving their time. As you can see in django's source code, EmailMultiAlterna...

Still can't find your answer? Check out these communities...

PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python