Added support for creating multipart/alternative email messages. Also allow

tweaking of main body MIME subtype for brave people. Fixed #3605.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@5548 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-06-27 12:18:05 +00:00
parent 2d082a34dc
commit 719a90391d
2 changed files with 62 additions and 7 deletions

View File

@ -169,6 +169,9 @@ class EmailMessage(object):
""" """
A container for email information. A container for email information.
""" """
content_subtype = 'plain'
multipart_subtype = 'mixed'
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
connection=None, attachments=None): connection=None, attachments=None):
self.to = to or [] self.to = to or []
@ -185,10 +188,10 @@ class EmailMessage(object):
return self.connection return self.connection
def message(self): def message(self):
msg = SafeMIMEText(self.body, 'plain', settings.DEFAULT_CHARSET) msg = SafeMIMEText(self.body, self.content_subtype, settings.DEFAULT_CHARSET)
if self.attachments: if self.attachments:
body_msg = msg body_msg = msg
msg = SafeMIMEMultipart() msg = SafeMIMEMultipart(_subtype=self.multipart_subtype)
if self.body: if self.body:
msg.attach(body_msg) msg.attach(body_msg)
for attachment in self.attachments: for attachment in self.attachments:
@ -216,14 +219,17 @@ class EmailMessage(object):
"""Send the email message.""" """Send the email message."""
return self.get_connection(fail_silently).send_messages([self]) return self.get_connection(fail_silently).send_messages([self])
def attach(self, filename, content=None, mimetype=None): def attach(self, filename=None, content=None, mimetype=None):
""" """
Attaches a file with the given filename and content. Attaches a file with the given filename and content. The filename can
be omitted (useful for multipart/alternative messages) and the mimetype
is guessed, if not provided.
Alternatively, the first parameter can be a MIMEBase subclass, which If the first parameter is a MIMEBase subclass it is inserted directly
is inserted directly into the resulting message attachments. into the resulting message attachments.
""" """
if isinstance(filename, MIMEBase): if isinstance(filename, MIMEBase):
assert content == mimetype == None
self.attachements.append(filename) self.attachements.append(filename)
else: else:
assert content is not None assert content is not None
@ -252,9 +258,22 @@ class EmailMessage(object):
attachment = MIMEBase(basetype, subtype) attachment = MIMEBase(basetype, subtype)
attachment.set_payload(content) attachment.set_payload(content)
Encoders.encode_base64(attachment) Encoders.encode_base64(attachment)
attachment.add_header('Content-Disposition', 'attachment', filename=filename) if filename:
attachment.add_header('Content-Disposition', 'attachment', filename=filename)
return attachment return attachment
class EmailMultiAlternatives(EmailMessage):
"""
A version of EmailMessage that makes it easy to send multipart/alternative
messages. For example, including text and HTML versions of the text is
made easier.
"""
multipart_subtype = 'alternative'
def attach_alternative(self, content, mimetype=None):
"""Attach an alternative content representation."""
self.attach(content=content, mimetype=mimetype)
def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None): def send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None):
""" """
Easy wrapper for sending a single message to a recipient list. All members Easy wrapper for sending a single message to a recipient list. All members

View File

@ -281,6 +281,42 @@ The class has the following methods:
message.attach_file('/images/weather_map.png') message.attach_file('/images/weather_map.png')
Sending alternative content types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is often useful to include multiple versions of the content in an e-mail.
For instance, sending both text and HTML versions of an e-mail. You can do
this using the ``EmailMultiAlternatives`` class. This sub-class of
``EmailMessage`` has an ``attach_alternative()`` method for including
extra versions of the message body in the e-mail. All the other methods
(including the class initialization) are inherited directly from
``EmailMessage``.
To send a text and HTML combination, you could write::
from django.core.mail import EmailMultiAlternatives
subject, from_email, to = ...
text_content = "This is an important message."
html_content = "<p>This is an <strong>important</strong> message."
msg = EmailMultiAlternatives(subject, text_content, from_email, to)
msg.attach_alternative(html_content, "text/html")
msg.send()
By default, the MIME type of the ``body`` parameter in an ``EmailMessage`` is
``"text/plain"``. It is good practice to leave this alone, since it guarantees
that any recipient will be able to read the e-mail, regardless of their mail
client. However, if you are confident that your recipients can handle an
alternative content type, you can use the ``content_subtype`` attribute on the
``EmailMessage`` class to change the main content type. The major type will
always be ``"text"``, but you can change to the subtype. For example::
msg = EmailMessage(subject, html_content, from_email, to)
msg.content_subtype = "html" # Main content is now text/html
msg.send()
SMTP network connections SMTP network connections
------------------------- -------------------------