Envoi de messages électroniques

Même si Python fournit une interface d’envoi de courriels via le module smtplib, Django propose quelques adaptateur légers supplémentaires. Ces adaptateurs sont fournis pour rendre encore plus direct l’envoi de courriels, pour faciliter le test d’envoi de courriels durant le développement et pour fournir la prise en charge sur les plates-formes qui ne peuvent pas utiliser SMTP.

Le code se trouve dans le module django.core.mail.

Exemples rapides

Utilisez send_mail() pour l’envoi direct de courriels. Par exemple, pour envoyer un message en texte brut :

from django.core.mail import send_mail

send_mail(
    "Subject here",
    "Here is the message.",
    "from@example.com",
    ["to@example.com"],
    fail_silently=False,
)

Lorsqu’il devient nécessaire de faire appel à des fonctionnalités d’envoi de messages plus avancées, utilisez EmailMessage ou EmailMultiAlternatives. Par exemple, pour envoyer un courriel incluant à la fois des versions HTML et texte brut avec un gabarit spécifique et des en-têtes personnalisés, vous pouvez adopter l’approche suivante :

from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string

# First, render the plain text content.
text_content = render_to_string(
    "templates/emails/my_email.txt",
    context={"my_variable": 42},
)

# Secondly, render the HTML content.
html_content = render_to_string(
    "templates/emails/my_email.html",
    context={"my_variable": 42},
)

# Then, create a multipart email instance.
msg = EmailMultiAlternatives(
    subject="Subject here",
    body=text_content,
    from_email="from@example.com",
    to=["to@example.com"],
    headers={"List-Unsubscribe": "<mailto:unsub@example.com>"},
)

# Lastly, attach the HTML content to the email instance and send.
msg.attach_alternative(html_content, "text/html")
msg.send()

Les messages sont envoyés en utilisant l’hôte et le port indiqués dans les réglages EMAIL_HOST et EMAIL_PORT. Les réglages EMAIL_HOST_USER et EMAIL_HOST_PASSWORD, si définis, sont utilisés pour s’authentifier auprès du serveur SMTP, et les réglages EMAIL_USE_TLS et EMAIL_USE_SSL indiquent si l’utilisation d’une connexion sécurisée est nécessaire.

Note

Le jeu de caractères des messages envoyés par django.core.mail est défini par la valeur du réglage DEFAULT_CHARSET.

send_mail()

send_mail(subject, message, from_email, recipient_list, *, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)[source]

Dans la plupart des cas, vous pouvez envoyer des courriels avec django.core.mail.send_mail().

Les paramètres subject, message, from_email et recipient_list sont obligatoires.

  • subject: une chaîne de caractères.

  • message: une chaîne de caractères.

  • from_email: une chaîne. Si None, Django utilise la valeur du réglage DEFAULT_FROM_EMAIL.

  • recipient_list: une liste de chaînes de caractères, chacune étant une adresse électronique. Chaque personne dans recipient_list verra les autres destinataires dans le champ « To: » du courriel.

The following parameters are optional, and must be given as keyword arguments if used.

  • fail_silently: une valeur booléenne. Avec la valeur False, send_mail() lève une exception smtplib.SMTPException en cas d’erreur. Consultez la liste des exceptions possibles dans la documentation de smtplib; elles sont toutes des sous-classes de SMTPException.

  • auth_user: le nom d’utilisateur facultatif utilisé pour s’authentifier auprès du serveur SMTP. Si ce paramètre est absent, c’est la valeur du réglage EMAIL_HOST_USER qui sera utilisée.

  • auth_password: le mot de passe facultatif utilisé pour s’authentifier auprès du serveur SMTP. Si ce paramètre est absent, c’est la valeur du réglage EMAIL_HOST_PASSWORD qui sera utilisée.

  • connection: le moteur de messagerie facultatif utilisé pour envoyer le message. Si ce paramètre est absent, c’est une instance du moteur par défaut qui sera utilisée. Consultez la documentation sur les moteurs de messagerie pour plus de détails.

  • html_message: si html_message est indiqué, le courriel produit sera un courriel multipart/alternative, avec message comme type de contenu text/plain et html_message comme type de contenu text/html .

La valeur renvoyée correspond au nombre de messages livrés avec succès (qui ne peut être que 0 ou 1 puisqu’elle ne peut envoyer qu’un message).

Deprecated since version 6.0: Passing fail_silently and later parameters as positional arguments is deprecated.

send_mass_mail()

send_mass_mail(datatuple, *, fail_silently=False, auth_user=None, auth_password=None, connection=None)[source]

django.core.mail.send_mass_mail() est prévu pour envoyer des courriels en masse.

datatuple est un tuple dans lequel chaque élément suit le format suivant :

(subject, message, from_email, recipient_list)

fail_silently, auth_user, auth_password and connection have the same functions as in send_mail(). They must be given as keyword arguments if used.

Each separate element of datatuple results in a separate email message. As in send_mail(), recipients in the same recipient_list will all see the other addresses in the email messages” « To: » field.

Par exemple, le code suivant envoie deux messages différents à deux ensembles différents de destinataires ; cependant, une seule connexion est ouverte vers le serveur de messagerie :

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)

La valeur renvoyée correspond au nombre de messages livrés avec succès.

Deprecated since version 6.0: Passing fail_silently and later parameters as positional arguments is deprecated.

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.

mail_admins()

mail_admins(subject, message, *, fail_silently=False, connection=None, html_message=None)[source]

django.core.mail.mail_admins() est un raccourci pour envoyer un courriel aux administrateurs du site, tels qu’ils apparaissent dans le réglage ADMINS.

mail_admins() préfixe le sujet avec la valeur du réglage EMAIL_SUBJECT_PREFIX (« [Django] » par défaut).

L’en-tête « From: » du courriel correspond à la valeur du réglage SERVER_EMAIL.

Cette méthode existe par commodité et pour une meilleure lisibilité.

Si html_message est indiqué, le courriel produit sera un courriel multipart/alternative, avec message comme type de contenu text/plain et html_message comme type de contenu text/html .

Deprecated since version 6.0: Passing fail_silently and later parameters as positional arguments is deprecated.

mail_managers()

mail_managers(subject, message, *, fail_silently=False, connection=None, html_message=None)[source]

django.core.mail.mail_managers() est équivalent à mail_admins(), excepté le fait qu’il envoie un courriel aux gestionnaires du site tels que définis dans le réglage MANAGERS.

Deprecated since version 6.0: Passing fail_silently and later parameters as positional arguments is deprecated.

Exemples

Ceci envoie un courriel unique à john@example.com et jane@example.com, les deux apparaissant dans le champ « 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 email:

datatuple = (
    ("Subject", "Message.", "from@example.com", ["john@example.com"]),
    ("Subject", "Message.", "from@example.com", ["jane@example.com"]),
)
send_mass_mail(datatuple)

Prévention de l’injection d’en-têtes

L”injection d’en-têtes est une faille de sécurité dans laquelle un attaquant insère des en-têtes de courriel supplémentaires pour contrôler les champs « To: » et « From: » des courriels que vos scripts produisent.

The Django email 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 email function (e.g. send_mail()) will raise ValueError and, hence, will not send the email. It’s your responsibility to validate all data before passing it to the email functions.

Si un message contient des en-têtes en début de chaîne, les en-têtes seront affichés en première partie du contenu du courriel.

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
from django.http import HttpResponse, HttpResponseRedirect


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 ValueError:
            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.")
Changed in Django 6.0:

Older versions raised django.core.mail.BadHeaderError for some invalid headers. This has been replaced with ValueError.

La classe EmailMessage

Django’s send_mail() and send_mass_mail() functions are actually thin wrappers that make use of the EmailMessage class.

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 email, you’ll need to create EmailMessage instances directly.

Note

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 email messages and retain the original functions only for backwards compatibility.

EmailMessage is responsible for creating the email message itself. The email backend is then responsible for sending the email.

For convenience, EmailMessage provides a send() method for sending a single email. If you need to send multiple messages, the email backend API provides an alternative.

Les objets EmailMessage

class EmailMessage[source]

The EmailMessage class is initialized with the following parameters. All parameters are optional and can be set at any time prior to calling the send() method.

The first four parameters can be passed as positional or keyword arguments, but must be in the given order if positional arguments are used:

  • subject: la ligne sujet du courriel.

  • body: le texte du corps. Cela doit être un message texte brut.

  • from_email: l’adresse de l’expéditeur. Les deux formes fred@example.com et "Fred" <fred@example.com> sont acceptées. Si le paramètre est absent, c’est le réglage DEFAULT_FROM_EMAIL qui est utilisé.

  • to: une liste ou un tuple d’adresses de destination.

The following parameters must be given as keyword arguments if used:

  • cc: une liste ou un tuple d’adresses de destination utilisées dans l’en-tête « Cc » lors de l’envoi du courriel.

  • bcc: une liste ou un tuple d’adresses à placer dans l’en-tête « Bcc » au moment d’envoyer le courriel.

  • reply_to: une liste ou un tuple d’adresses de destination utilisées dans l’en-tête « reply_to » lors de l’envoi du courriel.

  • attachments: A list of attachments to put on the message. Each can be an instance of MIMEPart or EmailAttachment, or a tuple with attributes (filename, content, mimetype).

    Changed in Django 5.2:

    Support for EmailAttachment items of attachments was added.

    Changed in Django 6.0:

    Support for MIMEPart objects in the attachments list was added.

    Deprecated since version 6.0: Support for Python’s legacy MIMEBase objects in attachments is deprecated. Use MIMEPart instead.

  • headers: un dictionnaire d’en-têtes à ajouter au message. Les clés sont les noms d’en-têtes, les valeurs sont les valeurs d’en-têtes. C’est à l’appelant de s’assurer que les noms et les valeurs d’en-têtes soient dans un format correct pour les courriels. L’attribut correspondant est extra_headers.

  • connection: An email backend instance. Use this parameter if you are sending the EmailMessage via send() and you want to use the same connection for multiple messages. If omitted, a new connection is created when send() is called. This parameter is ignored when using send_messages().

Deprecated since version 6.0: Passing all except the first four parameters as positional arguments is deprecated.

Par exemple :

from django.core.mail import EmailMessage

email = EmailMessage(
    subject="Hello",
    body="Body goes here",
    from_email="from@example.com",
    to=["to1@example.com", "to2@example.com"],
    bcc=["bcc@example.com"],
    reply_to=["another@example.com"],
    headers={"Message-ID": "foo"},
)

La classe possède les méthodes suivantes :

send(fail_silently=False)[source]

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. An empty list of recipients will not raise an exception. It will return 1 if the message was sent successfully, otherwise 0.

message(policy=email.policy.default)[source]

Constructs and returns a Python email.message.EmailMessage object representing the message to be sent.

The keyword argument policy allows specifying the set of rules for updating and serializing the representation of the message. It must be an email.policy.Policy object. Defaults to email.policy.default. In certain cases you may want to use SMTP, SMTPUTF8 or a custom policy. For example, django.core.mail.backends.smtp.EmailBackend uses the SMTP policy to ensure \r\n line endings as required by the SMTP protocol.

If you ever need to extend Django’s EmailMessage class, you’ll probably want to override this method to put the content you want into the Python EmailMessage object.

Changed in Django 6.0:

The policy keyword argument was added and the return type was updated to an instance of EmailMessage.

recipients()[source]

Returns a list of all the recipients of the message, whether they’re recorded in the to, cc 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(filename, content, mimetype)[source]
attach(mimepart)

Creates a new attachment and adds it to the message. There are two ways to call attach():

  • You can pass it three arguments: filename, content and mimetype. filename is the name of the file attachment as it will appear in the email, 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.

    Par exemple :

    message.attach("design.png", img_data, "image/png")
    

    If you specify a mimetype of message/rfc822, content can be a django.core.mail.EmailMessage or Python’s email.message.EmailMessage or email.message.Message.

    Pour un mimetype commençant par text/, le contenu attendu est une chaîne. Les données binaires sont décodées en utilisant UTF-8 et en cas d’échec, le type MIME sera transformé en application/octet-stream et les données seront jointes telles quelles.

  • Or for attachments requiring additional headers or parameters, you can pass attach() a single Python MIMEPart object. This will be attached directly to the resulting message. For example, to attach an inline image with a Content-ID:

    cid = email.utils.make_msgid()
    inline_image = email.message.MIMEPart()
    inline_image.set_content(
        image_data_bytes,
        maintype="image",
        subtype="png",
        disposition="inline",
        cid=f"<{cid}>",
    )
    message.attach(inline_image)
    message.attach_alternative(f'… <img src="cid:${cid}"> …', "text/html")
    

    Python’s email.contentmanager.set_content() documentation describes the supported arguments for MIMEPart.set_content().

    Changed in Django 6.0:

    Support for MIMEPart attachments was added.

    Deprecated since version 6.0: Support for email.mime.base.MIMEBase attachments is deprecated. Use MIMEPart instead.

attach_file(path, mimetype=None)[source]

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. You can use it like this:

message.attach_file("/images/weather_map.png")

For MIME types starting with text/, binary data is handled as in attach().

class EmailAttachment
New in Django 5.2.

Un tuple nommé pour stocker les pièces jointes d’un courriel.

Le tuple nommé possède les index suivants :

  • filename

  • content

  • mimetype

Envoi d’autres types de contenus

Envoi de plusieurs versions de contenus

It can be useful to include multiple versions of the content in an email; the classic example is to send both text and HTML versions of a message. With Django’s email library, you can do this using the EmailMultiAlternatives class.

class EmailMultiAlternatives[source]

Une sous-classe de EmailMessage qui permet des versions supplémentaires du corps du message du courriel via la méthode attach_alternative(). Cette classe hérite directement de toutes les méthodes de EmailMessage (y compris l’initialisation de la classe).

alternatives

A list of EmailAlternative named tuples. This is particularly useful in tests:

self.assertEqual(len(msg.alternatives), 1)
self.assertEqual(msg.alternatives[0].content, html_content)
self.assertEqual(msg.alternatives[0].mimetype, "text/html")

Les alternatives ne devraient être ajoutées que par la méthode attach_alternative(), ou passées directement dans le constructeur.

Changed in Django 5.2:

In older versions, alternatives was a list of regular tuples, as opposed to EmailAlternative named tuples.

attach_alternative(content, mimetype)[source]

Ajoute une représentation alternative du corps du message dans le courriel.

Par exemple, pour envoyer une combinaison de texte et de HTML, vous pourriez écrire :

from django.core.mail import EmailMultiAlternatives

subject = "hello"
from_email = "from@example.com"
to = "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()
body_contains(text)[source]
New in Django 5.2.

Renvoie une valeur booléenne indiquant si la valeur text fournie est contenue dans le corps body du courriel ou dans toutes les alternatives liées avec le type MIME text/*.

Cela peut être utile lors de tests de courriels. Par exemple :

def test_contains_email_content(self):
    subject = "Hello World"
    from_email = "from@example.com"
    to = "to@example.com"
    msg = EmailMultiAlternatives(subject, "I am content.", from_email, [to])
    msg.attach_alternative("<p>I am content.</p>", "text/html")

    self.assertIs(msg.body_contains("I am content"), True)
    self.assertIs(msg.body_contains("<p>I am content.</p>"), False)
class EmailAlternative
New in Django 5.2.

Un tuple nommé pour stocker les versions alternatives du contenu d’un courriel.

Le tuple nommé possède les index suivants :

  • content

  • mimetype

Mise à jour du type de contenu par défaut

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 email, 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 the subtype. For example:

msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html"  # Main content is now text/html
msg.send()

Moteurs de messagerie

L’envoi réel d’un courriel est géré par le moteur de messagerie.

La classe du moteur de messagerie possède les méthodes suivantes :

  • open() instancie une connexion persistante d’envoi de messages.

  • close() ferme la connexion actuelle vers le système d’envoi de messages.

  • send_messages(email_messages) sends a list of EmailMessage objects. If the connection is not open, this call will implicitly open the connection, and close the connection afterward. If the connection is already open, it will be left open after mail has been sent.

Il peut aussi être utilisé comme gestionnaire de contexte, ce qui appellera automatiquement les méthodes open() et close() nécessaires :

from django.core import mail

with mail.get_connection() as connection:
    mail.EmailMessage(
        subject1,
        body1,
        from1,
        [to1],
        connection=connection,
    ).send()
    mail.EmailMessage(
        subject2,
        body2,
        from2,
        [to2],
        connection=connection,
    ).send()

Obtention d’une instance d’un moteur de messagerie

La fonction get_connection() de django.core.mail renvoie une instance utilisable du moteur de messagerie.

get_connection(backend=None, *, fail_silently=False, **kwargs)[source]

Par défaut, une appel à get_connection() renvoie une instance du moteur de messagerie indiqué dans EMAIL_BACKEND. Si vous indiquez le paramètre backend, une instance de ce moteur sera créée.

The keyword-only 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.

Tous les autres paramètres nommés sont directement transmis au constructeur du moteur de messagerie.

Django est livré avec plusieurs moteurs de messagerie. À l’exception du moteur SMTP (moteur par défaut), ces moteurs ne sont utiles que pour les tests et le développement. Si vous avez des contraintes particulières dans l’envoi de messages, vous pouvez écrire votre propre moteur de messagerie.

Deprecated since version 6.0: Passing fail_silently as positional argument is deprecated.

Le moteur SMTP

class backends.smtp.EmailBackend(host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, use_ssl=None, timeout=None, ssl_keyfile=None, ssl_certfile=None, **kwargs)

C’est le moteur par défaut. Les courriels seront envoyés par un serveur SMTP.

La valeur de chaque paramètre est récupérée à partir du réglage correspondant si le paramètre vaut None:

Le moteur SMTP est la configuration par défaut héritée par Django. Si vous voulez la définir explicitement, mettez ce qui suit dans vos réglages :

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"

If unspecified, the default timeout will be the one provided by socket.getdefaulttimeout(), which defaults to None (no timeout).

Le moteur console

Au lieu d’envoyer vraiment des courriels, le moteur console ne fait qu’afficher sur la sortie standard les courriels qui auraient dû être envoyés. Par défaut, le moteur console écrit dans stdout. Vous pouvez utiliser un autre objet de type flux en indiquant le paramètre stream au moment de construire la connexion.

Pour utiliser ce moteur, mettez ce qui suit dans vos réglages :

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

Ce moteur n’est pas conçu pour être utilisé en production, il n’est fourni que par commodité et destiné à être utilisé durant le développement.

Le moteur fichier

The file backend writes emails 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 EMAIL_FILE_PATH setting or from the file_path keyword when creating a connection with get_connection().

Pour utiliser ce moteur, mettez ce qui suit dans vos réglages :

EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = "/tmp/app-messages"  # change this to a proper location

Ce moteur n’est pas conçu pour être utilisé en production, il n’est fourni que par commodité et destiné à être utilisé durant le développement.

Le moteur mémoire

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 EmailMessage instance for each message that would be sent.

Pour utiliser ce moteur, mettez ce qui suit dans vos réglages :

EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"

Ce moteur n’est pas conçu pour être utilisé en production, il n’est fourni que par commodité et destiné à être utilisé durant le développement et les tests.

L’exécuteur de tests de Django utilise automatiquement ce moteur pour les tests.

Le moteur bidon

Comme son nom l’indique, le moteur bidon (« dummy ») ne fait rien des messages reçus. Pour définir ce moteur, mettez ce qui suit dans vos réglages :

EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"

Ce moteur n’est pas conçu pour être utilisé en production, il n’est fourni que par commodité et destiné à être utilisé durant le développement.

There are community-maintained solutions too!

Django has a vibrant ecosystem. There are email backends highlighted on the Community Ecosystem page. The Django Packages Email grid has even more options for you!

Définition d’un moteur de messagerie personnalisé

Si vous devez modifier la façon dont les courriels sont envoyés, vous pouvez écrire votre propre moteur de messagerie. Le réglage EMAIL_BACKEND de votre fichier de réglages contiendra alors le chemin d’importation Python vers votre classe de moteur.

Custom email backends should subclass BaseEmailBackend that is located in the django.core.mail.backends.base module. A custom email backend must implement the send_messages(email_messages) method. This method receives a list of 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.

Envoi de plusieurs courriels

L’établissement et la fermeture d’une connexion SMTP (ou de toute autre connexion réseau, en fait) est un processus coûteux. Si vous avez beaucoup de courriels à envoyer, il est logique de recycler une connexion SMTP plutôt que de créer puis détruire une connexion lors de chaque envoi de message.

Il existe deux manières d’indiquer à un moteur de messagerie qu’il doit réutiliser une connexion.

Tout d’abord, vous pouvez utiliser la méthode send_messages() d’une connexion. Une liste d’instances EmailMessage (ou sous-classe) est envoyée, message par message en utilisant cette même connexion. Par conséquent, toute connexion définie individuellement sur l’un de ces messages sera ignorée.

For example, if you have a function called get_notification_email() that returns a list of EmailMessage objects representing some periodic email 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)

Dans cet exemple, l’appel à send_messages() ouvre une connexion au moteur, envoie la liste des messages et ferme à nouveau la connexion.

La seconde approche est d’utiliser les méthodes open() et close() du moteur de messagerie pour contrôler manuellement la connexion. send_messages() n’ouvre ou ne ferme pas manuellement de connexion si il y en a déjà une ouverte, ce qui fait qu’en ouvrant manuellement la connexion, vous contrôlez aussi quand elle sera fermée. Par exemple :

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()

Configuration de la messagerie pour le développement

À certains moments, vous ne voulez absolument pas que que Django envoie des courriels. Par exemple, pendant le développement d’un site Web, vous ne voulez certainement pas envoyer des milliers de courriels, mais vous voulez peut-être valider que ces courriels seraient envoyés aux bonnes personnes et aux bonnes conditions, et que leur contenu est correct.

La manière la plus simple de configurer la messagerie électronique lors du développement local est d’utiliser le moteur de messagerie console. Ce moteur redirige tous les courriels vers la sortie standard stdout, ce qui permet d’inspecter leur contenu.

Le moteur de messagerie fichier peut aussi être utile durant le développement ; ce moteur redirige le contenu de chaque connexion SMTP dans un fichier qui peut ensuite être examiné à souhait.

Une autre approche est d’utiliser un serveur SMTP « stupide » qui reçoit localement les courriels et les affiche dans le terminal, mais n’envoie rien plus loin. Le paquet aiosmtpd propose une manière de faire cela :

python -m pip install "aiosmtpd >= 1.4.5"

python -m aiosmtpd -n -l localhost:8025

Cette commande lance un serveur SMTP minimal écoutant sur le port 8025 de localhost. Ce serveur affiche sur la sortie standard tous les en-têtes des courriels ainsi que leur corps. Il ne vous reste plus qu’à définir adéquatement les réglages EMAIL_HOST et EMAIL_PORT. Pour une discussion plus détaillée au sujet des options de serveur SMTP, consultez la documentation du module aiosmtpd.

Pour plus d’informations sur les tests unitaires impliquant l’envoi de courriels par votre application, consultez la section Services de messagerie de la documentation sur les tests.