summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2009-11-03 12:53:26 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2009-11-03 12:53:26 +0000
commitaba5389326372be43b2a3bdcda16646fd197e807 (patch)
treea296f56691d3cb6da4dcbc3a99e16a7eab9a7c43 /docs
parent8287c27b1895ba56c6680295ff3d202fc7a4b64e (diff)
Fixed #10355 -- Added an API for pluggable e-mail backends.
Thanks to Andi Albrecht for his work on this patch, and to everyone else that contributed during design and development. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11709 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/internals/deprecation.txt3
-rw-r--r--docs/ref/settings.txt23
-rw-r--r--docs/topics/email.txt405
-rw-r--r--docs/topics/testing.txt12
4 files changed, 346 insertions, 97 deletions
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index cdb012e5e4..6cf62137dd 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -22,6 +22,9 @@ their deprecation, as per the :ref:`Django deprecation policy
* The old imports for CSRF functionality (``django.contrib.csrf.*``),
which moved to core in 1.2, will be removed.
+ * ``SMTPConnection``. The 1.2 release deprecated the ``SMTPConnection``
+ class in favor of a generic E-mail backend API.
+
* 2.0
* ``django.views.defaults.shortcut()``. This function has been moved
to ``django.contrib.contenttypes.views.shortcut()`` as part of the
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index a3120501aa..ad34e1d414 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -424,6 +424,29 @@ are not allowed to visit any page, systemwide. Use this for bad robots/crawlers.
This is only used if ``CommonMiddleware`` is installed (see
:ref:`topics-http-middleware`).
+.. setting:: EMAIL_BACKEND
+
+EMAIL_BACKEND
+-------------
+
+.. versionadded:: 1.2
+
+Default: ``'smtp'``
+
+The backend to use for sending emails. For the list of available backends see
+:ref:`topics-email`.
+
+.. setting:: EMAIL_FILE_PATH
+
+EMAIL_FILE_PATH
+---------------
+
+.. versionadded:: 1.2
+
+Default: Not defined
+
+The directory used by the ``file`` email backend to store output files.
+
.. setting:: EMAIL_HOST
EMAIL_HOST
diff --git a/docs/topics/email.txt b/docs/topics/email.txt
index c80a035b53..92e3c0263d 100644
--- a/docs/topics/email.txt
+++ b/docs/topics/email.txt
@@ -7,11 +7,13 @@ 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, to make sending e-mail
-extra quick.
+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
+email sending during development, and to provide support for platforms that
+can't use SMTP.
-The code lives in a single module: ``django.core.mail``.
+The code lives in the ``django.core.mail`` module.
.. _smtplib library: http://docs.python.org/library/smtplib.html
@@ -25,11 +27,11 @@ In two lines::
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.
+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::
@@ -42,7 +44,7 @@ send_mail()
The simplest way to send e-mail is using the function
``django.core.mail.send_mail()``. Here's its definition:
- .. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None)
+ .. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)
The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
are required.
@@ -62,6 +64,10 @@ are required.
* ``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
``EMAIL_HOST_PASSWORD`` setting.
+ * ``connection``: The optional email 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
@@ -71,26 +77,29 @@ send_mass_mail()
``django.core.mail.send_mass_mail()`` is intended to handle mass e-mailing.
Here's the definition:
- .. function:: send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None)
+ .. function:: send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)
``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 ``send_mail()``.
+as in :meth:`~django.core.mail.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' "To:" field.
+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.
send_mass_mail() vs. send_mail()
--------------------------------
-The main difference between ``send_mass_mail()`` and ``send_mail()`` is that
-``send_mail()`` opens a connection to the mail server each time it's executed,
-while ``send_mass_mail()`` uses a single connection for all of its messages.
-This makes ``send_mass_mail()`` slightly more efficient.
+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()
=============
@@ -98,7 +107,7 @@ mail_admins()
``django.core.mail.mail_admins()`` is a shortcut for sending an e-mail to the
site admins, as defined in the :setting:`ADMINS` setting. Here's the definition:
- .. function:: mail_admins(subject, message, fail_silently=False)
+ .. function:: mail_admins(subject, message, fail_silently=False, connection=None)
``mail_admins()`` prefixes the subject with the value of the
:setting:`EMAIL_SUBJECT_PREFIX` setting, which is ``"[Django] "`` by default.
@@ -115,7 +124,7 @@ mail_managers() function
sends an e-mail to the site managers, as defined in the :setting:`MANAGERS`
setting. Here's the definition:
- .. function:: mail_managers(subject, message, fail_silently=False)
+ .. function:: mail_managers(subject, message, fail_silently=False, connection=None)
Examples
========
@@ -145,7 +154,7 @@ 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. ``send_mail()``) will raise
+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.
@@ -178,41 +187,47 @@ from the request's POST data, sends that to admin@example.com and redirects to
.. _emailmessage-and-smtpconnection:
-The EmailMessage and SMTPConnection classes
-===========================================
+The EmailMessage class
+======================
.. versionadded:: 1.0
-Django's ``send_mail()`` and ``send_mass_mail()`` functions are actually thin
-wrappers that make use of the ``EmailMessage`` and ``SMTPConnection`` classes
-in ``django.core.mail``. If you ever need to customize the way Django sends
-e-mail, you can subclass these two classes to suit your needs.
+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::
- Not all features of the ``EmailMessage`` class are available through the
- ``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 ``EmailMessage`` instances directly.
+ 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.
- This is a design feature. ``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.
-In general, ``EmailMessage`` is responsible for creating the e-mail message
-itself. ``SMTPConnection`` is responsible for the network connection side of
-the operation. This means you can reuse the same connection (an
-``SMTPConnection`` instance) for multiple messages.
+For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
+``send()`` method for sending a single email. If you need to send multiple
+messages, the email backend API :ref:`provides an alternative
+<topics-sending-multiple-emails>`.
EmailMessage Objects
--------------------
.. class:: EmailMessage
-The ``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.
+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.
@@ -227,7 +242,7 @@ optional and can be set at any time prior to calling the ``send()`` method.
* ``bcc``: A list or tuple of addresses used in the "Bcc" header when
sending the e-mail.
- * ``connection``: An ``SMTPConnection`` instance. Use this parameter if
+ * ``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.
@@ -248,18 +263,18 @@ For example::
The class has the following methods:
- * ``send(fail_silently=False)`` sends the message, using either
- the connection that is specified in the ``connection``
- attribute, or creating a new connection if none already
- exists. If the keyword argument ``fail_silently`` is ``True``,
- exceptions raised while sending the message will be quashed.
+ * ``send(fail_silently=False)`` sends the message. If a connection was
+ specified when the email 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 ``EmailMessage`` class,
- you'll probably want to override this method to put the content you want
- into the MIME object.
+ ``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
@@ -299,13 +314,13 @@ The class has the following methods:
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
+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 ``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``.
+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::
@@ -318,41 +333,231 @@ To send a text and HTML combination, you could write::
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, 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 ``EmailMessage`` class to change the main content type. The
-major type will always be ``"text"``, but you can change it to the subtype. For
-example::
+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 it 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()
-SMTPConnection Objects
-----------------------
+.. _topic-email-backends:
-.. class:: SMTPConnection
+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 email-sending connection.
+
+ * ``close()`` closes the current email-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
+email 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 email 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 email sending requirements, you
+can :ref:`write your own email 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_POST`, :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'
+
+.. 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 email. This class has been
+ deprecated in favor of the generic email 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.
+
+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'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+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'
+ 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.
+
+In-memory backend
+~~~~~~~~~~~~~~~~~
-The ``SMTPConnection`` class is initialized with the host, port, username and
-password for the SMTP server. If you don't specify one or more of those
-options, they are read from your settings file.
+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 send. It's a list with an
+:class:`~django.core.mail.EmailMessage` instance for each message that would
+be send.
-If you're sending lots of messages at once, the ``send_messages()`` method of
-the ``SMTPConnection`` class is useful. It takes a list of ``EmailMessage``
-instances (or subclasses) and sends them over a single connection. For example,
-if you have a function called ``get_notification_email()`` that returns a
-list of ``EmailMessage`` objects representing some periodic e-mail you wish to
-send out, you could send this with::
+To specify this backend, put the following in your settings::
- connection = SMTPConnection() # Use default settings for connection
+ EMAIL_BACKEND = 'django.core.mail.backends.locmem'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development and testing.
+
+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'
+
+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 send 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.
+
+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 ``SMTPEmailBackend`` for a reference
+implementation.
+
+.. _topics-sending-multiple-emails:
+
+Sending multiple emails
+-----------------------
+
+Establishing and closing an SMTP connection (or any other network connection,
+for that matter) is an expensive process. If you have a lot of emails to send,
+it makes sense to reuse an SMTP connection, rather than creating and
+destroying a connection every time you want to send an email.
+
+There are two ways you tell an email 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 emails using
+a single call to send_messages::
+
+ from django.core import mail
+ connection = mail.get_connection() # Use default email 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
+email 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 email message that uses the connection
+ email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to1@example.com'], connection=connection)
+ email1.send() # Send the email
+
+ # 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 emails 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
-----------------------
+======================
The are times when you do not want Django to send e-mails at all. For example,
while developing a website, you probably don't want to send out thousands of
@@ -360,19 +565,41 @@ 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 a "dumb" e-mail
-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::
+The easiest way to test your project's use of e-mail is to use the ``console``
+email backend. This backend redirects all email to stdout, allowing you to
+inspect the content of mail.
+
+The ``file`` email 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 email headers and
-the email body. You then only need to set the :setting:`EMAIL_HOST` and
+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 more entailed testing and processing of e-mails locally, see the Python
-documentation on the `SMTP Server`_.
+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 email
+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.
diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt
index 25d2f083fd..6648461014 100644
--- a/docs/topics/testing.txt
+++ b/docs/topics/testing.txt
@@ -1104,6 +1104,8 @@ applications:
``target_status_code`` will be the url and status code for the final
point of the redirect chain.
+.. _topics-testing-email:
+
E-mail services
---------------
@@ -1117,7 +1119,7 @@ test every aspect of sending e-mail -- from the number of messages sent to the
contents of each message -- without actually sending the messages.
The test runner accomplishes this by transparently replacing the normal
-:class:`~django.core.mail.SMTPConnection` class with a different version.
+email backend with a testing backend.
(Don't worry -- this has no effect on any other e-mail senders outside of
Django, such as your machine's mail server, if you're running one.)
@@ -1128,14 +1130,8 @@ Django, such as your machine's mail server, if you're running one.)
During test running, each outgoing e-mail is saved in
``django.core.mail.outbox``. This is a simple list of all
:class:`~django.core.mail.EmailMessage` instances that have been sent.
-It does not exist under normal execution conditions, i.e., when you're not
-running unit tests. The outbox is created during test setup, along with the
-dummy :class:`~django.core.mail.SMTPConnection`. When the test framework is
-torn down, the standard :class:`~django.core.mail.SMTPConnection` class is
-restored, and the test outbox is destroyed.
-
The ``outbox`` attribute is a special attribute that is created *only* when
-the tests are run. It doesn't normally exist as part of the
+the ``locmem`` e-mail backend is used. It doesn't normally exist as part of the
:mod:`django.core.mail` module and you can't import it directly. The code
below shows how to access this attribute correctly.