diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/internals/deprecation.txt | 3 | ||||
| -rw-r--r-- | docs/ref/settings.txt | 23 | ||||
| -rw-r--r-- | docs/topics/email.txt | 405 | ||||
| -rw-r--r-- | docs/topics/testing.txt | 12 |
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. |
