248 votes

Créer des modèles d'e-mails avec Django

Je veux envoyer des courriers électroniques en HTML, en utilisant des modèles Django comme ceci :

<html>
<body>
hello <strong>{{username}}</strong>
your account activated.
<img src="mysite.com/logo.gif" />
</body>

Je ne peux pas trouver quelque chose sur send_mail et django-mailer n'envoie que des modèles HTML, sans données dynamiques.

Comment utiliser le moteur de modèles de Django pour générer des e-mails ?

3 votes

Avis Django 1.7 offre html_message en send_email stackoverflow.com/a/28476681/953553

0 votes

Salut @anakin, j'ai lutté avec ce problème pendant longtemps et j'ai décidé de créer un paquet pour cela. Je serais très heureux de recevoir vos commentaires : github.com/charlesthk/django-simple-mail

428voto

Dominic Rodger Points 44489

De les docs Pour envoyer des e-mails en HTML, vous devez utiliser d'autres types de contenu, comme ceci :

from django.core.mail import EmailMultiAlternatives

subject, from_email, to = 'hello', 'from@example.com', '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()

Vous aurez probablement besoin de deux modèles pour votre courrier électronique - un modèle en texte brut qui ressemble à ceci, stocké dans votre répertoire de modèles sous le nom de email.txt :

Hello {{ username }} - your account is activated.

et un autre en HTML, stocké sous email.html :

Hello <strong>{{ username }}</strong> - your account is activated.

Vous pouvez ensuite envoyer un e-mail en utilisant ces deux modèles en utilisant l'option get_template comme ceci :

from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template
from django.template import Context

plaintext = get_template('email.txt')
htmly     = get_template('email.html')

d = Context({ 'username': username })

subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
text_content = plaintext.render(d)
html_content = htmly.render(d)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()

49 votes

Je pense que vous pouvez simplifier cela avec render_to_string ce qui vous permettrait de perdre les lignes séparées qui assignent les modèles à l'utilisateur. plaintext y htmly et il suffit de définir les modèles et les contextes lorsque vous définissez l'option text_content y html_content .

0 votes

@cms_mgr Pouvez-vous préciser ce que vous voulez dire et comment nous pouvons l'utiliser ?

3 votes

@akki voir la réponse d'andi ci-dessous, qui simplifie également la partie alternative grâce au paramètre html_message ajouté à send_email() dans Django 1.7

28voto

Darb Points 591

J'ai fait django-templated-email dans un effort pour résoudre ce problème, inspiré par cette solution (et le besoin, à un moment donné, de passer de l'utilisation de modèles django à l'utilisation d'un ensemble de modèles mailchimp etc. pour les emails transactionnels, pour mon propre projet). Il s'agit encore d'un travail en cours, mais pour l'exemple ci-dessus, il faut le faire :

from templated_email import send_templated_mail
send_templated_mail(
        'email',
        'from@example.com',
        ['to@example.com'],
        { 'username':username }
    )

Avec l'ajout de ce qui suit à settings.py (pour compléter l'exemple) :

TEMPLATED_EMAIL_DJANGO_SUBJECTS = {'email':'hello',}

Il recherchera automatiquement des modèles nommés 'templated_email/email.txt' et 'templated_email/email.html' pour les parties plain et html respectivement, dans les répertoires/chargeurs de modèles normaux de django (il se plaindra s'il n'en trouve pas au moins un).

1 votes

Ça m'a l'air bien. Je l'ai raccourci et l'ai mis dans un ticket pour ajouter django.shortcuts.send_templated_mail : code.djangoproject.com/ticket/17193

0 votes

Cool, content de voir qu'il est proposé comme outil pour le noyau de django. Le cas d'utilisation que je fais de la librairie est un peu plus important que le simple raccourci (basculement facile entre les fournisseurs de messagerie qui ont des API clé/valeur pour l'envoi de messages), mais il me semble que c'est une fonctionnalité manquante dans le noyau.

16voto

Rrrrrrrrrk Points 593

Utilisez EmailMultiAlternatives et render_to_string pour utiliser deux modèles alternatifs (un en texte brut et un en html) :

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

c = Context({'username': username})    
text_content = render_to_string('mail/email.txt', c)
html_content = render_to_string('mail/email.html', c)

email = EmailMultiAlternatives('Subject', text_content)
email.attach_alternative(html_content, "text/html")
email.to = ['to@example.com']
email.send()

3voto

Rendu du corps de l'email vous-même d'abord.

3voto

idbill Points 61

Il y a une erreur dans l'exemple.... si vous l'utilisez tel qu'il est écrit, l'erreur suivante se produit :

< type 'exceptions.Exception' > : l'objet 'dict' n'a pas d'attribut 'render_context'.

Vous devrez ajouter l'importation suivante :

from django.template import Context

et changer le dictionnaire pour qu'il soit :

d = Context({ 'username': username })

Voir http://docs.djangoproject.com/en/1.2/ref/templates/api/#rendering-a-context

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X