parts/django/docs/topics/email.txt
changeset 69 c6bca38c1cbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parts/django/docs/topics/email.txt	Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,618 @@
+==============
+Sending e-mail
+==============
+
+.. module:: django.core.mail
+   :synopsis: Helpers to easily send e-mail.
+
+Although Python makes sending e-mail relatively easy via the `smtplib
+library`_, Django provides a couple of light wrappers over it. These wrappers
+are provided to make sending e-mail extra quick, to make it easy to test
+e-mail sending during development, and to provide support for platforms that
+can't use SMTP.
+
+The code lives in the ``django.core.mail`` module.
+
+.. _smtplib library: http://docs.python.org/library/smtplib.html
+
+Quick example
+=============
+
+In two lines::
+
+    from django.core.mail import send_mail
+
+    send_mail('Subject here', 'Here is the message.', 'from@example.com',
+        ['to@example.com'], fail_silently=False)
+
+Mail is sent using the SMTP host and port specified in the
+:setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The
+:setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if
+set, are used to authenticate to the SMTP server, and the
+:setting:`EMAIL_USE_TLS` setting controls whether a secure connection is used.
+
+.. note::
+
+    The character set of e-mail sent with ``django.core.mail`` will be set to
+    the value of your :setting:`DEFAULT_CHARSET` setting.
+
+send_mail()
+===========
+
+.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)
+
+The simplest way to send e-mail is using
+``django.core.mail.send_mail()``.
+
+The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
+are required.
+
+    * ``subject``: A string.
+    * ``message``: A string.
+    * ``from_email``: A string.
+    * ``recipient_list``: A list of strings, each an e-mail address. Each
+      member of ``recipient_list`` will see the other recipients in the "To:"
+      field of the e-mail message.
+    * ``fail_silently``: A boolean. If it's ``False``, ``send_mail`` will raise
+      an ``smtplib.SMTPException``. See the `smtplib docs`_ for a list of
+      possible exceptions, all of which are subclasses of ``SMTPException``.
+    * ``auth_user``: The optional username to use to authenticate to the SMTP
+      server. If this isn't provided, Django will use the value of the
+      :setting:`EMAIL_HOST_USER` setting.
+    * ``auth_password``: The optional password to use to authenticate to the
+      SMTP server. If this isn't provided, Django will use the value of the
+      :setting:`EMAIL_HOST_PASSWORD` setting.
+    * ``connection``: The optional e-mail backend to use to send the mail.
+      If unspecified, an instance of the default backend will be used.
+      See the documentation on :ref:`E-mail backends <topic-email-backends>`
+      for more details.
+
+.. _smtplib docs: http://docs.python.org/library/smtplib.html
+
+send_mass_mail()
+================
+
+.. function:: send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)
+
+``django.core.mail.send_mass_mail()`` is intended to handle mass e-mailing.
+
+``datatuple`` is a tuple in which each element is in this format::
+
+    (subject, message, from_email, recipient_list)
+
+``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions
+as in :meth:`~django.core.mail.send_mail()`.
+
+Each separate element of ``datatuple`` results in a separate e-mail message.
+As in :meth:`~django.core.mail.send_mail()`, recipients in the same
+``recipient_list`` will all see the other addresses in the e-mail messages'
+"To:" field.
+
+For example, the following code would send two different messages to
+two different sets of recipients; however, only one connection to the
+mail server would be opened::
+
+    message1 = ('Subject here', 'Here is the message', 'from@example.com, ['first@example.com', 'other@example.com'])
+    message2 = ('Another Subject', 'Here is another message', 'from@example.com', ['second@test.com'])
+    send_mass_mail((message1, message2), fail_silently=False)
+
+send_mass_mail() vs. send_mail()
+--------------------------------
+
+The main difference between :meth:`~django.core.mail.send_mass_mail()` and
+:meth:`~django.core.mail.send_mail()` is that
+:meth:`~django.core.mail.send_mail()` opens a connection to the mail server
+each time it's executed, while :meth:`~django.core.mail.send_mass_mail()` uses
+a single connection for all of its messages. This makes
+:meth:`~django.core.mail.send_mass_mail()` slightly more efficient.
+
+mail_admins()
+=============
+
+.. function:: mail_admins(subject, message, fail_silently=False, connection=None)
+
+``django.core.mail.mail_admins()`` is a shortcut for sending an e-mail to the
+site admins, as defined in the :setting:`ADMINS` setting.
+
+``mail_admins()`` prefixes the subject with the value of the
+:setting:`EMAIL_SUBJECT_PREFIX` setting, which is ``"[Django] "`` by default.
+
+The "From:" header of the e-mail will be the value of the
+:setting:`SERVER_EMAIL` setting.
+
+This method exists for convenience and readability.
+
+mail_managers()
+===============
+
+.. function:: mail_managers(subject, message, fail_silently=False, connection=None)
+
+``django.core.mail.mail_managers()`` is just like ``mail_admins()``, except it
+sends an e-mail to the site managers, as defined in the :setting:`MANAGERS`
+setting.
+
+Examples
+========
+
+This sends a single e-mail to john@example.com and jane@example.com, with them
+both appearing in the "To:"::
+
+    send_mail('Subject', 'Message.', 'from@example.com',
+        ['john@example.com', 'jane@example.com'])
+
+This sends a message to john@example.com and jane@example.com, with them both
+receiving a separate e-mail::
+
+    datatuple = (
+        ('Subject', 'Message.', 'from@example.com', ['john@example.com']),
+        ('Subject', 'Message.', 'from@example.com', ['jane@example.com']),
+    )
+    send_mass_mail(datatuple)
+
+Preventing header injection
+===========================
+
+`Header injection`_ is a security exploit in which an attacker inserts extra
+e-mail headers to control the "To:" and "From:" in e-mail messages that your
+scripts generate.
+
+The Django e-mail functions outlined above all protect against header injection
+by forbidding newlines in header values. If any ``subject``, ``from_email`` or
+``recipient_list`` contains a newline (in either Unix, Windows or Mac style),
+the e-mail function (e.g. :meth:`~django.core.mail.send_mail()`) will raise
+``django.core.mail.BadHeaderError`` (a subclass of ``ValueError``) and, hence,
+will not send the e-mail. It's your responsibility to validate all data before
+passing it to the e-mail functions.
+
+If a ``message`` contains headers at the start of the string, the headers will
+simply be printed as the first bit of the e-mail message.
+
+Here's an example view that takes a ``subject``, ``message`` and ``from_email``
+from the request's POST data, sends that to admin@example.com and redirects to
+"/contact/thanks/" when it's done::
+
+    from django.core.mail import send_mail, BadHeaderError
+
+    def send_email(request):
+        subject = request.POST.get('subject', '')
+        message = request.POST.get('message', '')
+        from_email = request.POST.get('from_email', '')
+        if subject and message and from_email:
+            try:
+                send_mail(subject, message, from_email, ['admin@example.com'])
+            except BadHeaderError:
+                return HttpResponse('Invalid header found.')
+            return HttpResponseRedirect('/contact/thanks/')
+        else:
+            # In reality we'd use a form class
+            # to get proper validation errors.
+            return HttpResponse('Make sure all fields are entered and valid.')
+
+.. _Header injection: http://www.nyphp.org/phundamentals/email_header_injection.php
+
+.. _emailmessage-and-smtpconnection:
+
+The EmailMessage class
+======================
+
+.. versionadded:: 1.0
+
+Django's :meth:`~django.core.mail.send_mail()` and
+:meth:`~django.core.mail.send_mass_mail()` functions are actually thin
+wrappers that make use of the :class:`~django.core.mail.EmailMessage` class.
+
+Not all features of the :class:`~django.core.mail.EmailMessage` class are
+available through the :meth:`~django.core.mail.send_mail()` and related
+wrapper functions. If you wish to use advanced features, such as BCC'ed
+recipients, file attachments, or multi-part e-mail, you'll need to create
+:class:`~django.core.mail.EmailMessage` instances directly.
+
+.. note::
+    This is a design feature. :meth:`~django.core.mail.send_mail()` and
+    related functions were originally the only interface Django provided.
+    However, the list of parameters they accepted was slowly growing over
+    time. It made sense to move to a more object-oriented design for e-mail
+    messages and retain the original functions only for backwards
+    compatibility.
+
+:class:`~django.core.mail.EmailMessage` is responsible for creating the e-mail
+message itself. The :ref:`e-mail backend <topic-email-backends>` is then
+responsible for sending the e-mail.
+
+For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
+``send()`` method for sending a single e-mail. If you need to send multiple
+messages, the e-mail backend API :ref:`provides an alternative
+<topics-sending-multiple-emails>`.
+
+EmailMessage Objects
+--------------------
+
+.. class:: EmailMessage
+
+The :class:`~django.core.mail.EmailMessage` class is initialized with the
+following parameters (in the given order, if positional arguments are used).
+All parameters are optional and can be set at any time prior to calling the
+``send()`` method.
+
+    * ``subject``: The subject line of the e-mail.
+
+    * ``body``: The body text. This should be a plain text message.
+
+    * ``from_email``: The sender's address. Both ``fred@example.com`` and
+      ``Fred <fred@example.com>`` forms are legal. If omitted, the
+      :setting:`DEFAULT_FROM_EMAIL` setting is used.
+
+    * ``to``: A list or tuple of recipient addresses.
+
+    * ``bcc``: A list or tuple of addresses used in the "Bcc" header when
+      sending the e-mail.
+
+    * ``connection``: An e-mail backend instance. Use this parameter if
+      you want to use the same connection for multiple messages. If omitted, a
+      new connection is created when ``send()`` is called.
+
+    * ``attachments``: A list of attachments to put on the message. These can
+      be either ``email.MIMEBase.MIMEBase`` instances, or ``(filename,
+      content, mimetype)`` triples.
+
+    * ``headers``: A dictionary of extra headers to put on the message. The
+      keys are the header name, values are the header values. It's up to the
+      caller to ensure header names and values are in the correct format for
+      an e-mail message.
+
+For example::
+
+    email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
+                ['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
+                headers = {'Reply-To': 'another@example.com'})
+
+The class has the following methods:
+
+    * ``send(fail_silently=False)`` sends the message. If a connection was
+      specified when the e-mail was constructed, that connection will be used.
+      Otherwise, an instance of the default backend will be instantiated and
+      used. If the keyword argument ``fail_silently`` is ``True``, exceptions
+      raised while sending the message will be quashed.
+
+    * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a
+      subclass of Python's ``email.MIMEText.MIMEText`` class) or a
+      ``django.core.mail.SafeMIMEMultipart`` object holding the message to be
+      sent. If you ever need to extend the
+      :class:`~django.core.mail.EmailMessage` class, you'll probably want to
+      override this method to put the content you want into the MIME object.
+
+    * ``recipients()`` returns a list of all the recipients of the message,
+      whether they're recorded in the ``to`` or ``bcc`` attributes. This is
+      another method you might need to override when subclassing, because the
+      SMTP server needs to be told the full list of recipients when the message
+      is sent. If you add another way to specify recipients in your class, they
+      need to be returned from this method as well.
+
+    * ``attach()`` creates a new file attachment and adds it to the message.
+      There are two ways to call ``attach()``:
+
+       * You can pass it a single argument that is an
+         ``email.MIMEBase.MIMEBase`` instance. This will be inserted directly
+         into the resulting message.
+
+       * Alternatively, you can pass ``attach()`` three arguments:
+         ``filename``, ``content`` and ``mimetype``. ``filename`` is the name
+         of the file attachment as it will appear in the e-mail, ``content`` is
+         the data that will be contained inside the attachment and
+         ``mimetype`` is the optional MIME type for the attachment. If you
+         omit ``mimetype``, the MIME content type will be guessed from the
+         filename of the attachment.
+
+         For example::
+
+            message.attach('design.png', img_data, 'image/png')
+
+    * ``attach_file()`` creates a new attachment using a file from your
+      filesystem. Call it with the path of the file to attach and, optionally,
+      the MIME type to use for the attachment. If the MIME type is omitted, it
+      will be guessed from the filename. The simplest use would be::
+
+        message.attach_file('/images/weather_map.png')
+
+.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
+
+Sending alternative content types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It can be useful to include multiple versions of the content in an e-mail; the
+classic example is to send both text and HTML versions of a message. With
+Django's e-mail library, you can do this using the ``EmailMultiAlternatives``
+class. This subclass of :class:`~django.core.mail.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 :class:`~django.core.mail.EmailMessage`.
+
+To send a text and HTML combination, you could write::
+
+    from django.core.mail import EmailMultiAlternatives
+
+    subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
+    text_content = 'This is an important message.'
+    html_content = '<p>This is an <strong>important</strong> message.</p>'
+    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
+:class:`~django.core.mail.EmailMessage` is ``"text/plain"``. It is good
+practice to leave this alone, because 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
+:class:`~django.core.mail.EmailMessage` class to change the main content type.
+The major type will always be ``"text"``, but you can change the
+subtype. For example::
+
+    msg = EmailMessage(subject, html_content, from_email, [to])
+    msg.content_subtype = "html"  # Main content is now text/html
+    msg.send()
+
+.. _topic-email-backends:
+
+E-Mail Backends
+===============
+
+.. versionadded:: 1.2
+
+The actual sending of an e-mail is handled by the e-mail backend.
+
+The e-mail backend class has the following methods:
+
+    * ``open()`` instantiates an long-lived e-mail-sending connection.
+
+    * ``close()`` closes the current e-mail-sending connection.
+
+    * ``send_messages(email_messages)`` sends a list of
+      :class:`~django.core.mail.EmailMessage` objects. If the connection is
+      not open, this call will implicitly open the connection, and close the
+      connection afterwards. If the connection is already open, it will be
+      left open after mail has been sent.
+
+Obtaining an instance of an e-mail backend
+------------------------------------------
+
+The :meth:`get_connection` function in ``django.core.mail`` returns an
+instance of the e-mail backend that you can use.
+
+.. currentmodule:: django.core.mail
+
+.. function:: get_connection(backend=None, fail_silently=False, *args, **kwargs)
+
+By default, a call to ``get_connection()`` will return an instance of the
+e-mail backend specified in :setting:`EMAIL_BACKEND`. If you specify the
+``backend`` argument, an instance of that backend will be instantiated.
+
+The ``fail_silently`` argument controls how the backend should handle errors.
+If ``fail_silently`` is True, exceptions during the e-mail sending process
+will be silently ignored.
+
+All other arguments are passed directly to the constructor of the
+e-mail backend.
+
+Django ships with several e-mail sending backends. With the exception of the
+SMTP backend (which is the default), these backends are only useful during
+testing and development. If you have special e-mail sending requirements, you
+can :ref:`write your own e-mail backend <topic-custom-email-backend>`.
+
+.. _topic-email-smtp-backend:
+
+SMTP backend
+~~~~~~~~~~~~
+
+This is the default backend. E-mail will be sent through a SMTP server.
+The server address and authentication credentials are set in the
+:setting:`EMAIL_HOST`, :setting:`EMAIL_PORT`, :setting:`EMAIL_HOST_USER`,
+:setting:`EMAIL_HOST_PASSWORD` and :setting:`EMAIL_USE_TLS` settings in your
+settings file.
+
+The SMTP backend is the default configuration inherited by Django. If you
+want to specify it explicitly, put the following in your settings::
+
+    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+
+.. admonition:: SMTPConnection objects
+
+    Prior to version 1.2, Django provided a
+    :class:`~django.core.mail.SMTPConnection` class. This class provided a way
+    to directly control the use of SMTP to send e-mail. This class has been
+    deprecated in favor of the generic e-mail backend API.
+
+    For backwards compatibility :class:`~django.core.mail.SMTPConnection` is
+    still available in ``django.core.mail`` as an alias for the SMTP backend.
+    New code should use :meth:`~django.core.mail.get_connection` instead.
+
+.. _topic-email-console-backend:
+
+Console backend
+~~~~~~~~~~~~~~~
+
+Instead of sending out real e-mails the console backend just writes the
+e-mails that would be send to the standard output. By default, the console
+backend writes to ``stdout``. You can use a different stream-like object by
+providing the ``stream`` keyword argument when constructing the connection.
+
+To specify this backend, put the following in your settings::
+
+    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-email-file-backend:
+
+File backend
+~~~~~~~~~~~~
+
+The file backend writes e-mails to a file. A new file is created for each new
+session that is opened on this backend. The directory to which the files are
+written is either taken from the :setting:`EMAIL_FILE_PATH` setting or from
+the ``file_path`` keyword when creating a connection with
+:meth:`~django.core.mail.get_connection`.
+
+To specify this backend, put the following in your settings::
+
+    EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
+    EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-email-memory-backend:
+
+In-memory backend
+~~~~~~~~~~~~~~~~~
+
+The ``'locmem'`` backend stores messages in a special attribute of the
+``django.core.mail`` module. The ``outbox`` attribute is created when the
+first message is sent. It's a list with an
+:class:`~django.core.mail.EmailMessage` instance for each message that would
+be send.
+
+To specify this backend, put the following in your settings::
+
+  EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development and testing.
+
+.. _topic-email-dummy-backend:
+
+Dummy backend
+~~~~~~~~~~~~~
+
+As the name suggests the dummy backend does nothing with your messages. To
+specify this backend, put the following in your settings::
+
+   EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-custom-email-backend:
+
+Defining a custom e-mail backend
+--------------------------------
+
+If you need to change how e-mails are sent you can write your own e-mail
+backend. The ``EMAIL_BACKEND`` setting in your settings file is then the
+Python import path for your backend class.
+
+Custom e-mail backends should subclass ``BaseEmailBackend`` that is located in
+the ``django.core.mail.backends.base`` module. A custom e-mail backend must
+implement the ``send_messages(email_messages)`` method. This method receives a
+list of :class:`~django.core.mail.EmailMessage` instances and returns the
+number of successfully delivered messages. If your backend has any concept of
+a persistent session or connection, you should also implement the ``open()``
+and ``close()`` methods. Refer to ``smtp.EmailBackend`` for a reference
+implementation.
+
+.. _topics-sending-multiple-emails:
+
+Sending multiple e-mails
+------------------------
+
+Establishing and closing an SMTP connection (or any other network connection,
+for that matter) is an expensive process. If you have a lot of e-mails to send,
+it makes sense to reuse an SMTP connection, rather than creating and
+destroying a connection every time you want to send an e-mail.
+
+There are two ways you tell an e-mail backend to reuse a connection.
+
+Firstly, you can use the ``send_messages()`` method. ``send_messages()`` takes
+a list of :class:`~django.core.mail.EmailMessage` instances (or subclasses),
+and sends them all using a single connection.
+
+For example, if you have a function called ``get_notification_email()`` that
+returns a list of :class:`~django.core.mail.EmailMessage` objects representing
+some periodic e-mail you wish to send out, you could send these e-mails using
+a single call to send_messages::
+
+    from django.core import mail
+    connection = mail.get_connection()   # Use default e-mail connection
+    messages = get_notification_email()
+    connection.send_messages(messages)
+
+In this example, the call to ``send_messages()`` opens a connection on the
+backend, sends the list of messages, and then closes the connection again.
+
+The second approach is to use the ``open()`` and ``close()`` methods on the
+e-mail backend to manually control the connection. ``send_messages()`` will not
+manually open or close the connection if it is already open, so if you
+manually open the connection, you can control when it is closed. For example::
+
+    from django.core import mail
+    connection = mail.get_connection()
+
+    # Manually open the connection
+    connection.open()
+
+    # Construct an e-mail message that uses the connection
+    email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+                              ['to1@example.com'], connection=connection)
+    email1.send() # Send the e-mail
+
+    # Construct two more messages
+    email2 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+                              ['to2@example.com'])
+    email3 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+                              ['to3@example.com'])
+
+    # Send the two e-mails in a single call -
+    connection.send_messages([email2, email3])
+    # The connection was already open so send_messages() doesn't close it.
+    # We need to manually close the connection.
+    connection.close()
+
+
+Testing e-mail sending
+======================
+
+There are times when you do not want Django to send e-mails at
+all. For example, while developing a Web site, you probably don't want
+to send out thousands of e-mails -- but you may want to validate that
+e-mails will be sent to the right people under the right conditions,
+and that those e-mails will contain the correct content.
+
+The easiest way to test your project's use of e-mail is to use the ``console``
+e-mail backend. This backend redirects all e-mail to stdout, allowing you to
+inspect the content of mail.
+
+The ``file`` e-mail backend can also be useful during development -- this backend
+dumps the contents of every SMTP connection to a file that can be inspected
+at your leisure.
+
+Another approach is to use a "dumb" SMTP server that receives the e-mails
+locally and displays them to the terminal, but does not actually send
+anything. Python has a built-in way to accomplish this with a single command::
+
+    python -m smtpd -n -c DebuggingServer localhost:1025
+
+This command will start a simple SMTP server listening on port 1025 of
+localhost. This server simply prints to standard output all e-mail headers and
+the e-mail body. You then only need to set the :setting:`EMAIL_HOST` and
+:setting:`EMAIL_PORT` accordingly, and you are set.
+
+For a more detailed discussion of testing and processing of e-mails locally,
+see the Python documentation on the `SMTP Server`_.
+
+.. _SMTP Server: http://docs.python.org/library/smtpd.html
+
+SMTPConnection
+==============
+
+.. class:: SMTPConnection
+
+.. deprecated:: 1.2
+
+The ``SMTPConnection`` class has been deprecated in favor of the generic e-mail
+backend API.
+
+For backwards compatibility ``SMTPConnection`` is still available in
+``django.core.mail`` as an alias for the :ref:`SMTP backend
+<topic-email-smtp-backend>`. New code should use
+:meth:`~django.core.mail.get_connection` instead.