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"
self.msg.send()
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?
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.
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:
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.
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.