PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/docs/topics/email.txt

https://code.google.com/p/mango-py/
Plain Text | 628 lines | 455 code | 173 blank | 0 comment | 0 complexity | 3f647558dc4b104dc404d0545f8c6733 MD5 | raw file
  1==============
  2Sending e-mail
  3==============
  4
  5.. module:: django.core.mail
  6   :synopsis: Helpers to easily send e-mail.
  7
  8Although Python makes sending e-mail relatively easy via the `smtplib
  9library`_, Django provides a couple of light wrappers over it. These wrappers
 10are provided to make sending e-mail extra quick, to make it easy to test
 11e-mail sending during development, and to provide support for platforms that
 12can't use SMTP.
 13
 14The code lives in the ``django.core.mail`` module.
 15
 16.. _smtplib library: http://docs.python.org/library/smtplib.html
 17
 18Quick example
 19=============
 20
 21In two lines::
 22
 23    from django.core.mail import send_mail
 24
 25    send_mail('Subject here', 'Here is the message.', 'from@example.com',
 26        ['to@example.com'], fail_silently=False)
 27
 28Mail is sent using the SMTP host and port specified in the
 29:setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The
 30:setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if
 31set, are used to authenticate to the SMTP server, and the
 32:setting:`EMAIL_USE_TLS` setting controls whether a secure connection is used.
 33
 34.. note::
 35
 36    The character set of e-mail sent with ``django.core.mail`` will be set to
 37    the value of your :setting:`DEFAULT_CHARSET` setting.
 38
 39send_mail()
 40===========
 41
 42.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)
 43
 44The simplest way to send e-mail is using
 45``django.core.mail.send_mail()``.
 46
 47The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
 48are required.
 49
 50    * ``subject``: A string.
 51    * ``message``: A string.
 52    * ``from_email``: A string.
 53    * ``recipient_list``: A list of strings, each an e-mail address. Each
 54      member of ``recipient_list`` will see the other recipients in the "To:"
 55      field of the e-mail message.
 56    * ``fail_silently``: A boolean. If it's ``False``, ``send_mail`` will raise
 57      an ``smtplib.SMTPException``. See the `smtplib docs`_ for a list of
 58      possible exceptions, all of which are subclasses of ``SMTPException``.
 59    * ``auth_user``: The optional username to use to authenticate to the SMTP
 60      server. If this isn't provided, Django will use the value of the
 61      :setting:`EMAIL_HOST_USER` setting.
 62    * ``auth_password``: The optional password to use to authenticate to the
 63      SMTP server. If this isn't provided, Django will use the value of the
 64      :setting:`EMAIL_HOST_PASSWORD` setting.
 65    * ``connection``: The optional e-mail backend to use to send the mail.
 66      If unspecified, an instance of the default backend will be used.
 67      See the documentation on :ref:`E-mail backends <topic-email-backends>`
 68      for more details.
 69
 70.. _smtplib docs: http://docs.python.org/library/smtplib.html
 71
 72send_mass_mail()
 73================
 74
 75.. function:: send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)
 76
 77``django.core.mail.send_mass_mail()`` is intended to handle mass e-mailing.
 78
 79``datatuple`` is a tuple in which each element is in this format::
 80
 81    (subject, message, from_email, recipient_list)
 82
 83``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions
 84as in :meth:`~django.core.mail.send_mail()`.
 85
 86Each separate element of ``datatuple`` results in a separate e-mail message.
 87As in :meth:`~django.core.mail.send_mail()`, recipients in the same
 88``recipient_list`` will all see the other addresses in the e-mail messages'
 89"To:" field.
 90
 91For example, the following code would send two different messages to
 92two different sets of recipients; however, only one connection to the
 93mail server would be opened::
 94
 95    message1 = ('Subject here', 'Here is the message', 'from@example.com', ['first@example.com', 'other@example.com'])
 96    message2 = ('Another Subject', 'Here is another message', 'from@example.com', ['second@test.com'])
 97    send_mass_mail((message1, message2), fail_silently=False)
 98
 99send_mass_mail() vs. send_mail()
100--------------------------------
101
102The main difference between :meth:`~django.core.mail.send_mass_mail()` and
103:meth:`~django.core.mail.send_mail()` is that
104:meth:`~django.core.mail.send_mail()` opens a connection to the mail server
105each time it's executed, while :meth:`~django.core.mail.send_mass_mail()` uses
106a single connection for all of its messages. This makes
107:meth:`~django.core.mail.send_mass_mail()` slightly more efficient.
108
109mail_admins()
110=============
111
112.. function:: mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)
113
114``django.core.mail.mail_admins()`` is a shortcut for sending an e-mail to the
115site admins, as defined in the :setting:`ADMINS` setting.
116
117``mail_admins()`` prefixes the subject with the value of the
118:setting:`EMAIL_SUBJECT_PREFIX` setting, which is ``"[Django] "`` by default.
119
120The "From:" header of the e-mail will be the value of the
121:setting:`SERVER_EMAIL` setting.
122
123This method exists for convenience and readability.
124
125.. versionchanged:: 1.3
126
127If ``html_message`` is provided, the resulting e-mail will be a
128multipart/alternative e-mail with ``message`` as the "text/plain"
129content type and ``html_message`` as the "text/html" content type.
130
131mail_managers()
132===============
133
134.. function:: mail_managers(subject, message, fail_silently=False, connection=None, html_message=None)
135
136``django.core.mail.mail_managers()`` is just like ``mail_admins()``, except it
137sends an e-mail to the site managers, as defined in the :setting:`MANAGERS`
138setting.
139
140Examples
141========
142
143This sends a single e-mail to john@example.com and jane@example.com, with them
144both appearing in the "To:"::
145
146    send_mail('Subject', 'Message.', 'from@example.com',
147        ['john@example.com', 'jane@example.com'])
148
149This sends a message to john@example.com and jane@example.com, with them both
150receiving a separate e-mail::
151
152    datatuple = (
153        ('Subject', 'Message.', 'from@example.com', ['john@example.com']),
154        ('Subject', 'Message.', 'from@example.com', ['jane@example.com']),
155    )
156    send_mass_mail(datatuple)
157
158Preventing header injection
159===========================
160
161`Header injection`_ is a security exploit in which an attacker inserts extra
162e-mail headers to control the "To:" and "From:" in e-mail messages that your
163scripts generate.
164
165The Django e-mail functions outlined above all protect against header injection
166by forbidding newlines in header values. If any ``subject``, ``from_email`` or
167``recipient_list`` contains a newline (in either Unix, Windows or Mac style),
168the e-mail function (e.g. :meth:`~django.core.mail.send_mail()`) will raise
169``django.core.mail.BadHeaderError`` (a subclass of ``ValueError``) and, hence,
170will not send the e-mail. It's your responsibility to validate all data before
171passing it to the e-mail functions.
172
173If a ``message`` contains headers at the start of the string, the headers will
174simply be printed as the first bit of the e-mail message.
175
176Here's an example view that takes a ``subject``, ``message`` and ``from_email``
177from the request's POST data, sends that to admin@example.com and redirects to
178"/contact/thanks/" when it's done::
179
180    from django.core.mail import send_mail, BadHeaderError
181
182    def send_email(request):
183        subject = request.POST.get('subject', '')
184        message = request.POST.get('message', '')
185        from_email = request.POST.get('from_email', '')
186        if subject and message and from_email:
187            try:
188                send_mail(subject, message, from_email, ['admin@example.com'])
189            except BadHeaderError:
190                return HttpResponse('Invalid header found.')
191            return HttpResponseRedirect('/contact/thanks/')
192        else:
193            # In reality we'd use a form class
194            # to get proper validation errors.
195            return HttpResponse('Make sure all fields are entered and valid.')
196
197.. _Header injection: http://www.nyphp.org/phundamentals/email_header_injection.php
198
199.. _emailmessage-and-smtpconnection:
200
201The EmailMessage class
202======================
203
204Django's :meth:`~django.core.mail.send_mail()` and
205:meth:`~django.core.mail.send_mass_mail()` functions are actually thin
206wrappers that make use of the :class:`~django.core.mail.EmailMessage` class.
207
208Not all features of the :class:`~django.core.mail.EmailMessage` class are
209available through the :meth:`~django.core.mail.send_mail()` and related
210wrapper functions. If you wish to use advanced features, such as BCC'ed
211recipients, file attachments, or multi-part e-mail, you'll need to create
212:class:`~django.core.mail.EmailMessage` instances directly.
213
214.. note::
215    This is a design feature. :meth:`~django.core.mail.send_mail()` and
216    related functions were originally the only interface Django provided.
217    However, the list of parameters they accepted was slowly growing over
218    time. It made sense to move to a more object-oriented design for e-mail
219    messages and retain the original functions only for backwards
220    compatibility.
221
222:class:`~django.core.mail.EmailMessage` is responsible for creating the e-mail
223message itself. The :ref:`e-mail backend <topic-email-backends>` is then
224responsible for sending the e-mail.
225
226For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
227``send()`` method for sending a single e-mail. If you need to send multiple
228messages, the e-mail backend API :ref:`provides an alternative
229<topics-sending-multiple-emails>`.
230
231EmailMessage Objects
232--------------------
233
234.. class:: EmailMessage
235
236The :class:`~django.core.mail.EmailMessage` class is initialized with the
237following parameters (in the given order, if positional arguments are used).
238All parameters are optional and can be set at any time prior to calling the
239``send()`` method.
240
241.. versionchanged:: 1.3
242   The ``cc`` argument was added.
243
244    * ``subject``: The subject line of the e-mail.
245
246    * ``body``: The body text. This should be a plain text message.
247
248    * ``from_email``: The sender's address. Both ``fred@example.com`` and
249      ``Fred <fred@example.com>`` forms are legal. If omitted, the
250      :setting:`DEFAULT_FROM_EMAIL` setting is used.
251
252    * ``to``: A list or tuple of recipient addresses.
253
254    * ``bcc``: A list or tuple of addresses used in the "Bcc" header when
255      sending the e-mail.
256
257    * ``connection``: An e-mail backend instance. Use this parameter if
258      you want to use the same connection for multiple messages. If omitted, a
259      new connection is created when ``send()`` is called.
260
261    * ``attachments``: A list of attachments to put on the message. These can
262      be either ``email.MIMEBase.MIMEBase`` instances, or ``(filename,
263      content, mimetype)`` triples.
264
265    * ``headers``: A dictionary of extra headers to put on the message. The
266      keys are the header name, values are the header values. It's up to the
267      caller to ensure header names and values are in the correct format for
268      an e-mail message.
269
270    * ``cc``: A list or tuple of recipient addresses used in the "Cc" header
271      when sending the e-mail.
272
273For example::
274
275    email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
276                ['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
277                headers = {'Reply-To': 'another@example.com'})
278
279The class has the following methods:
280
281    * ``send(fail_silently=False)`` sends the message. If a connection was
282      specified when the e-mail was constructed, that connection will be used.
283      Otherwise, an instance of the default backend will be instantiated and
284      used. If the keyword argument ``fail_silently`` is ``True``, exceptions
285      raised while sending the message will be quashed.
286
287    * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a
288      subclass of Python's ``email.MIMEText.MIMEText`` class) or a
289      ``django.core.mail.SafeMIMEMultipart`` object holding the message to be
290      sent. If you ever need to extend the
291      :class:`~django.core.mail.EmailMessage` class, you'll probably want to
292      override this method to put the content you want into the MIME object.
293
294    * ``recipients()`` returns a list of all the recipients of the message,
295      whether they're recorded in the ``to`` or ``bcc`` attributes. This is
296      another method you might need to override when subclassing, because the
297      SMTP server needs to be told the full list of recipients when the message
298      is sent. If you add another way to specify recipients in your class, they
299      need to be returned from this method as well.
300
301    * ``attach()`` creates a new file attachment and adds it to the message.
302      There are two ways to call ``attach()``:
303
304       * You can pass it a single argument that is an
305         ``email.MIMEBase.MIMEBase`` instance. This will be inserted directly
306         into the resulting message.
307
308       * Alternatively, you can pass ``attach()`` three arguments:
309         ``filename``, ``content`` and ``mimetype``. ``filename`` is the name
310         of the file attachment as it will appear in the e-mail, ``content`` is
311         the data that will be contained inside the attachment and
312         ``mimetype`` is the optional MIME type for the attachment. If you
313         omit ``mimetype``, the MIME content type will be guessed from the
314         filename of the attachment.
315
316         For example::
317
318            message.attach('design.png', img_data, 'image/png')
319
320    * ``attach_file()`` creates a new attachment using a file from your
321      filesystem. Call it with the path of the file to attach and, optionally,
322      the MIME type to use for the attachment. If the MIME type is omitted, it
323      will be guessed from the filename. The simplest use would be::
324
325        message.attach_file('/images/weather_map.png')
326
327.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
328
329Sending alternative content types
330~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
331
332It can be useful to include multiple versions of the content in an e-mail; the
333classic example is to send both text and HTML versions of a message. With
334Django's e-mail library, you can do this using the ``EmailMultiAlternatives``
335class. This subclass of :class:`~django.core.mail.EmailMessage` has an
336``attach_alternative()`` method for including extra versions of the message
337body in the e-mail. All the other methods (including the class initialization)
338are inherited directly from :class:`~django.core.mail.EmailMessage`.
339
340To send a text and HTML combination, you could write::
341
342    from django.core.mail import EmailMultiAlternatives
343
344    subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
345    text_content = 'This is an important message.'
346    html_content = '<p>This is an <strong>important</strong> message.</p>'
347    msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
348    msg.attach_alternative(html_content, "text/html")
349    msg.send()
350
351By default, the MIME type of the ``body`` parameter in an
352:class:`~django.core.mail.EmailMessage` is ``"text/plain"``. It is good
353practice to leave this alone, because it guarantees that any recipient will be
354able to read the e-mail, regardless of their mail client. However, if you are
355confident that your recipients can handle an alternative content type, you can
356use the ``content_subtype`` attribute on the
357:class:`~django.core.mail.EmailMessage` class to change the main content type.
358The major type will always be ``"text"``, but you can change the
359subtype. For example::
360
361    msg = EmailMessage(subject, html_content, from_email, [to])
362    msg.content_subtype = "html"  # Main content is now text/html
363    msg.send()
364
365.. _topic-email-backends:
366
367E-Mail Backends
368===============
369
370.. versionadded:: 1.2
371
372The actual sending of an e-mail is handled by the e-mail backend.
373
374The e-mail backend class has the following methods:
375
376    * ``open()`` instantiates an long-lived e-mail-sending connection.
377
378    * ``close()`` closes the current e-mail-sending connection.
379
380    * ``send_messages(email_messages)`` sends a list of
381      :class:`~django.core.mail.EmailMessage` objects. If the connection is
382      not open, this call will implicitly open the connection, and close the
383      connection afterwards. If the connection is already open, it will be
384      left open after mail has been sent.
385
386Obtaining an instance of an e-mail backend
387------------------------------------------
388
389The :meth:`get_connection` function in ``django.core.mail`` returns an
390instance of the e-mail backend that you can use.
391
392.. currentmodule:: django.core.mail
393
394.. function:: get_connection(backend=None, fail_silently=False, *args, **kwargs)
395
396By default, a call to ``get_connection()`` will return an instance of the
397e-mail backend specified in :setting:`EMAIL_BACKEND`. If you specify the
398``backend`` argument, an instance of that backend will be instantiated.
399
400The ``fail_silently`` argument controls how the backend should handle errors.
401If ``fail_silently`` is True, exceptions during the e-mail sending process
402will be silently ignored.
403
404All other arguments are passed directly to the constructor of the
405e-mail backend.
406
407Django ships with several e-mail sending backends. With the exception of the
408SMTP backend (which is the default), these backends are only useful during
409testing and development. If you have special e-mail sending requirements, you
410can :ref:`write your own e-mail backend <topic-custom-email-backend>`.
411
412.. _topic-email-smtp-backend:
413
414SMTP backend
415~~~~~~~~~~~~
416
417This is the default backend. E-mail will be sent through a SMTP server.
418The server address and authentication credentials are set in the
419:setting:`EMAIL_HOST`, :setting:`EMAIL_PORT`, :setting:`EMAIL_HOST_USER`,
420:setting:`EMAIL_HOST_PASSWORD` and :setting:`EMAIL_USE_TLS` settings in your
421settings file.
422
423The SMTP backend is the default configuration inherited by Django. If you
424want to specify it explicitly, put the following in your settings::
425
426    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
427
428.. admonition:: SMTPConnection objects
429
430    Prior to version 1.2, Django provided a
431    :class:`~django.core.mail.SMTPConnection` class. This class provided a way
432    to directly control the use of SMTP to send e-mail. This class has been
433    deprecated in favor of the generic e-mail backend API.
434
435    For backwards compatibility :class:`~django.core.mail.SMTPConnection` is
436    still available in ``django.core.mail`` as an alias for the SMTP backend.
437    New code should use :meth:`~django.core.mail.get_connection` instead.
438
439.. _topic-email-console-backend:
440
441Console backend
442~~~~~~~~~~~~~~~
443
444Instead of sending out real e-mails the console backend just writes the
445e-mails that would be send to the standard output. By default, the console
446backend writes to ``stdout``. You can use a different stream-like object by
447providing the ``stream`` keyword argument when constructing the connection.
448
449To specify this backend, put the following in your settings::
450
451    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
452
453This backend is not intended for use in production -- it is provided as a
454convenience that can be used during development.
455
456.. _topic-email-file-backend:
457
458File backend
459~~~~~~~~~~~~
460
461The file backend writes e-mails to a file. A new file is created for each new
462session that is opened on this backend. The directory to which the files are
463written is either taken from the :setting:`EMAIL_FILE_PATH` setting or from
464the ``file_path`` keyword when creating a connection with
465:meth:`~django.core.mail.get_connection`.
466
467To specify this backend, put the following in your settings::
468
469    EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
470    EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
471
472This backend is not intended for use in production -- it is provided as a
473convenience that can be used during development.
474
475.. _topic-email-memory-backend:
476
477In-memory backend
478~~~~~~~~~~~~~~~~~
479
480The ``'locmem'`` backend stores messages in a special attribute of the
481``django.core.mail`` module. The ``outbox`` attribute is created when the
482first message is sent. It's a list with an
483:class:`~django.core.mail.EmailMessage` instance for each message that would
484be send.
485
486To specify this backend, put the following in your settings::
487
488  EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
489
490This backend is not intended for use in production -- it is provided as a
491convenience that can be used during development and testing.
492
493.. _topic-email-dummy-backend:
494
495Dummy backend
496~~~~~~~~~~~~~
497
498As the name suggests the dummy backend does nothing with your messages. To
499specify this backend, put the following in your settings::
500
501   EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
502
503This backend is not intended for use in production -- it is provided as a
504convenience that can be used during development.
505
506.. _topic-custom-email-backend:
507
508Defining a custom e-mail backend
509--------------------------------
510
511If you need to change how e-mails are sent you can write your own e-mail
512backend. The :setting:`EMAIL_BACKEND` setting in your settings file is then
513the Python import path for your backend class.
514
515Custom e-mail backends should subclass ``BaseEmailBackend`` that is located in
516the ``django.core.mail.backends.base`` module. A custom e-mail backend must
517implement the ``send_messages(email_messages)`` method. This method receives a
518list of :class:`~django.core.mail.EmailMessage` instances and returns the
519number of successfully delivered messages. If your backend has any concept of
520a persistent session or connection, you should also implement the ``open()``
521and ``close()`` methods. Refer to ``smtp.EmailBackend`` for a reference
522implementation.
523
524.. _topics-sending-multiple-emails:
525
526Sending multiple e-mails
527------------------------
528
529Establishing and closing an SMTP connection (or any other network connection,
530for that matter) is an expensive process. If you have a lot of e-mails to send,
531it makes sense to reuse an SMTP connection, rather than creating and
532destroying a connection every time you want to send an e-mail.
533
534There are two ways you tell an e-mail backend to reuse a connection.
535
536Firstly, you can use the ``send_messages()`` method. ``send_messages()`` takes
537a list of :class:`~django.core.mail.EmailMessage` instances (or subclasses),
538and sends them all using a single connection.
539
540For example, if you have a function called ``get_notification_email()`` that
541returns a list of :class:`~django.core.mail.EmailMessage` objects representing
542some periodic e-mail you wish to send out, you could send these e-mails using
543a single call to send_messages::
544
545    from django.core import mail
546    connection = mail.get_connection()   # Use default e-mail connection
547    messages = get_notification_email()
548    connection.send_messages(messages)
549
550In this example, the call to ``send_messages()`` opens a connection on the
551backend, sends the list of messages, and then closes the connection again.
552
553The second approach is to use the ``open()`` and ``close()`` methods on the
554e-mail backend to manually control the connection. ``send_messages()`` will not
555manually open or close the connection if it is already open, so if you
556manually open the connection, you can control when it is closed. For example::
557
558    from django.core import mail
559    connection = mail.get_connection()
560
561    # Manually open the connection
562    connection.open()
563
564    # Construct an e-mail message that uses the connection
565    email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
566                              ['to1@example.com'], connection=connection)
567    email1.send() # Send the e-mail
568
569    # Construct two more messages
570    email2 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
571                              ['to2@example.com'])
572    email3 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
573                              ['to3@example.com'])
574
575    # Send the two e-mails in a single call -
576    connection.send_messages([email2, email3])
577    # The connection was already open so send_messages() doesn't close it.
578    # We need to manually close the connection.
579    connection.close()
580
581
582Testing e-mail sending
583======================
584
585There are times when you do not want Django to send e-mails at
586all. For example, while developing a Web site, you probably don't want
587to send out thousands of e-mails -- but you may want to validate that
588e-mails will be sent to the right people under the right conditions,
589and that those e-mails will contain the correct content.
590
591The easiest way to test your project's use of e-mail is to use the ``console``
592e-mail backend. This backend redirects all e-mail to stdout, allowing you to
593inspect the content of mail.
594
595The ``file`` e-mail backend can also be useful during development -- this backend
596dumps the contents of every SMTP connection to a file that can be inspected
597at your leisure.
598
599Another approach is to use a "dumb" SMTP server that receives the e-mails
600locally and displays them to the terminal, but does not actually send
601anything. Python has a built-in way to accomplish this with a single command::
602
603    python -m smtpd -n -c DebuggingServer localhost:1025
604
605This command will start a simple SMTP server listening on port 1025 of
606localhost. This server simply prints to standard output all e-mail headers and
607the e-mail body. You then only need to set the :setting:`EMAIL_HOST` and
608:setting:`EMAIL_PORT` accordingly, and you are set.
609
610For a more detailed discussion of testing and processing of e-mails locally,
611see the Python documentation on the `SMTP Server`_.
612
613.. _SMTP Server: http://docs.python.org/library/smtpd.html
614
615SMTPConnection
616==============
617
618.. class:: SMTPConnection
619
620.. deprecated:: 1.2
621
622The ``SMTPConnection`` class has been deprecated in favor of the generic e-mail
623backend API.
624
625For backwards compatibility ``SMTPConnection`` is still available in
626``django.core.mail`` as an alias for the :ref:`SMTP backend
627<topic-email-smtp-backend>`. New code should use
628:meth:`~django.core.mail.get_connection` instead.