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. SiNone, Django utilise la valeur du réglageDEFAULT_FROM_EMAIL.recipient_list: une liste de chaînes de caractères, chacune étant une adresse électronique. Chaque personne dansrecipient_listverra 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 valeurFalse,send_mail()lève une exceptionsmtplib.SMTPExceptionen cas d’erreur. Consultez la liste des exceptions possibles dans la documentation desmtplib; elles sont toutes des sous-classes deSMTPException.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églageEMAIL_HOST_USERqui 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églageEMAIL_HOST_PASSWORDqui 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: sihtml_messageest indiqué, le courriel produit sera un courriel multipart/alternative, avecmessagecomme type de contenu text/plain ethtml_messagecomme 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()¶
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.")
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
EmailMessageclass is initialized with the following parameters. All parameters are optional and can be set at any time prior to calling thesend()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 formesfred@example.comet"Fred" <fred@example.com>sont acceptées. Si le paramètre est absent, c’est le réglageDEFAULT_FROM_EMAILqui 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 ofMIMEPartorEmailAttachment, or a tuple with attributes(filename, content, mimetype).Changed in Django 5.2:Support for
EmailAttachmentitems ofattachmentswas added.Changed in Django 6.0:Support for
MIMEPartobjects in theattachmentslist was added.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 estextra_headers.connection: An email backend instance. Use this parameter if you are sending theEmailMessageviasend()and you want to use the same connection for multiple messages. If omitted, a new connection is created whensend()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_silentlyisTrue, exceptions raised while sending the message will be quashed. An empty list of recipients will not raise an exception. It will return1if the message was sent successfully, otherwise0.
- message(policy=email.policy.default)[source]¶
Constructs and returns a Python
email.message.EmailMessageobject representing the message to be sent.The keyword argument
policyallows specifying the set of rules for updating and serializing the representation of the message. It must be anemail.policy.Policyobject. Defaults toemail.policy.default. In certain cases you may want to useSMTP,SMTPUTF8or a custom policy. For example,django.core.mail.backends.smtp.EmailBackenduses theSMTPpolicy to ensure\r\nline endings as required by the SMTP protocol.If you ever need to extend Django’s
EmailMessageclass, 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
policykeyword argument was added and the return type was updated to an instance ofEmailMessage.
- recipients()[source]¶
Returns a list of all the recipients of the message, whether they’re recorded in the
to,ccorbccattributes. 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,contentandmimetype.filenameis the name of the file attachment as it will appear in the email,contentis the data that will be contained inside the attachment andmimetypeis the optional MIME type for the attachment. If you omitmimetype, 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
mimetypeof message/rfc822,contentcan be adjango.core.mail.EmailMessageor Python’semail.message.EmailMessageoremail.message.Message.Pour un
mimetypecommenç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 PythonMIMEPartobject. This will be attached directly to the resulting message. For example, to attach an inline image with a Content-ID:import email.utils from email.message import MIMEPart from django.core.mail import EmailMultiAlternatives message = EmailMultiAlternatives(...) image_data_bytes = ... # Load image as bytes # Create a random Content-ID, including angle brackets cid = email.utils.make_msgid() inline_image = email.message.MIMEPart() inline_image.set_content( image_data_bytes, maintype="image", subtype="png", # or "jpeg", etc. depending on the image type disposition="inline", cid=cid, ) message.attach(inline_image) # Refer to Content-ID in HTML without angle brackets message.attach_alternative(f'… <img src="cid:{cid[1:-1]}"> …', "text/html")
Python’s
email.contentmanager.set_content()documentation describes the supported arguments forMIMEPart.set_content().Changed in Django 6.0:Support for
MIMEPartattachments was added.Deprecated since version 6.0: Support for
email.mime.base.MIMEBaseattachments is deprecated. UseMIMEPartinstead.
- 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 :
filenamecontentmimetype
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
EmailMessagequi permet des versions supplémentaires du corps du message du courriel via la méthodeattach_alternative(). Cette classe hérite directement de toutes les méthodes deEmailMessage(y compris l’initialisation de la classe).- alternatives¶
A list of
EmailAlternativenamed 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,
alternativeswas a list of regular tuples, as opposed toEmailAlternativenamed 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
textfournie est contenue dans le corpsbodydu courriel ou dans toutes les alternatives liées avec le type MIMEtext/*.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 :
contentmimetype
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 ofEmailMessageobjects. 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.
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:host:EMAIL_HOSTport:EMAIL_PORTusername:EMAIL_HOST_USERpassword:EMAIL_HOST_PASSWORDuse_tls:EMAIL_USE_TLSuse_ssl:EMAIL_USE_SSLtimeout:EMAIL_TIMEOUTssl_keyfile:EMAIL_SSL_KEYFILEssl_certfile:EMAIL_SSL_CERTFILE
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
timeoutwill be the one provided bysocket.getdefaulttimeout(), which defaults toNone(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.