Index: django/core/mail.py
===================================================================
--- django/core/mail.py	(revision 4308)
+++ django/core/mail.py	(working copy)
@@ -2,6 +2,7 @@
 
 from django.conf import settings
 from email.MIMEText import MIMEText
+from email.MIMEMultipart import MIMEMultipart
 from email.Header import Header
 import smtplib, rfc822
 import socket
@@ -29,13 +30,19 @@
     """
     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
 
-def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD):
+def send_mass_mail(datatuple, fail_silently=False, auth_user=settings.EMAIL_HOST_USER, auth_password=settings.EMAIL_HOST_PASSWORD, suppress_recipients=False):
     """
     Given a datatuple of (subject, message, from_email, recipient_list), sends
     each message to each recipient list. Returns the number of e-mails sent.
-
+    
+    If message is a list or tuple, the email will be sent as multipart; the
+    first element in message will be used as the plain-text version, and the
+    second will be used as the HTML version.
     If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
     If auth_user and auth_password are set, they're used to log in.
+    If suppress_recipients is True, the first address in the recipients list
+    will be inserted into the 'To:' field and all other addresses will be
+    inserted into the 'Bcc:' field.
     """
     try:
         server = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT)
@@ -50,10 +57,20 @@
         if not recipient_list:
             continue
         from_email = from_email or settings.DEFAULT_FROM_EMAIL
-        msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
+        if isinstance(message, basestring):
+            msg = SafeMIMEText(message, 'plain', settings.DEFAULT_CHARSET)
+        else:
+            msg = MIMEMultipart('alternative')
+            msg.attach(MIMEText(message[0]))
+            msg.attach(MIMEText(message[1], 'html'))
         msg['Subject'] = subject
         msg['From'] = from_email
-        msg['To'] = ', '.join(recipient_list)
+        if suppress_recipients:
+            msg['To'] = recipient_list[0]
+            if len(recipient_list) > 1:
+                msg['Bcc'] = ', '.join(recipient_list[1:])
+        else:
+            msg['To'] = ', '.join(recipient_list)
         msg['Date'] = rfc822.formatdate()
         try:
             random_bits = str(random.getrandbits(64))
Index: docs/email.txt
===================================================================
--- docs/email.txt	(revision 4308)
+++ docs/email.txt	(working copy)
@@ -65,18 +65,27 @@
 Here's the definition::
 
     send_mass_mail(datatuple, fail_silently=False,
-        auth_user=EMAIL_HOST_USER, auth_password=EMAIL_HOST_PASSWORD):
+        auth_user=EMAIL_HOST_USER,
+        auth_password=EMAIL_HOST_PASSWORD,
+        suppress_recipients=False):
 
 ``datatuple`` is a tuple in which each element is in this format::
 
     (subject, message, from_email, recipient_list)
 
+If the ``message`` in a particular element of ``datatuple`` is a list or tuple,
+it will result in a multpart MIME message; the first element of ``message`` will
+be sent as ``text/plain``, and the second will be sent as ``text/html``.
+
 ``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions
 as in ``send_mail()``.
 
 Each separate element of ``datatuple`` results in a separate e-mail message.
 As in ``send_mail()``, recipients in the same ``recipient_list`` will all see
-the other addresses in the e-mail messages's "To:" field.
+the other addresses in the e-mail messages's "To:" field. To suppress all but
+a single address (useful for newsletters or mailing lists), use
+``suppress_recipients=True``; this will use the first address in the "To:"
+field, and place all other addresses in the "Bcc:" field.
 
 send_mass_mail() vs. send_mail()
 --------------------------------
