3

From Django 1.7, it is possible to send_email() with a new parameter: html_message. Unfortunately, there is not a comprehensive guide (newby friendly) on how to use it (or at least I could not find it).

I need to make sent emails nice and, thus, I'm trying to figure out how to include my message into a html/css template. I've read many posts about this subject, but most of them refer to previous version of Django. This post is for Django 1.7 but the answer shows the usage of a very basic html file.

my_html_message.html

<html lang="en">
 <head>
  <link href="path/to/application.css" rel="stylesheet">
 </head>
 <body>
  <div class="email_header">
    [..]
    <a href="http://mysite.it"><img src="images/logo.png"/></a>
  </div>
  <div class="email_body">
   [..]
   {{my_message}}
  </div>
 </body>

my_message.txt

 Dear {{username}}, 
 you won {{money}}.

my_function.py

def my_send_email(request):
 subject = 'Test html email'
 from = 'my@email.com'
 to = 'yours@email.com'
 my_context = Context({'username': user.username,
             'money': user.money})
 html_message = render_to_string('mail/my_html_message.html', c)
 message = render_to_string('mail/my_message.txt', c)
 send_mail(subject,
          message,
          from,
          [to],
          html_message=html_message)

How can I pass to my_html_message.html the file my_message.txt with my_context and send an email with a custom style?

Community
  • 1
  • 1
user123892
  • 1,243
  • 3
  • 21
  • 38

2 Answers2

3

With include:

<html lang="en">
 <head>
  <link href="path/to/application.css" rel="stylesheet">
 </head>
 <body>
  <div class="email_header">
    [..]
    <a href="http://mysite.it"><img src="images/logo.png"/></a>
  </div>
  <div class="email_body">
   [..]
   {% include "my_message.txt" %}
  </div>
 </body>
Andrés Pérez-Albela H.
  • 4,003
  • 1
  • 18
  • 29
1

When you write a HTML template for emails, you should consider write your style inline:

<div style="display: none;"></div>

Because some email clients won't display your styles as you expect. BTW, let's suppose you have a template styled in the convenient way.

<html lang="en">
 <head>
  <link href="path/to/application.css" rel="stylesheet">
 </head>
 <body>
  <div class="email_header">
    [..]
    <a href="http://mysite.it"><img src="images/logo.png"/></a>
  </div>
  <div class="email_body">
   [..]
   Dear {{ name }}
   You won {{ money }}

   {# Or you could use include #}
  </div>
 </body>

I will assume that you've configured a directory for your templates, and it's working well. To send an HTML template with a context you could do this:

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

class Email():

    @staticmethod
    def send_html_email(*args, **kwargs):
        from_email = kwargs.get('from_email', 'default@email.from')
        context = Context(kwargs.get('context'))
        template = get_template(kwargs.get('template_name'))
        body = template.render(context)
        subject = kwargs.get('subject', 'Default subject here')
        headers = kwargs.get('headers', {})

        message = EmailMultiAlternatives(
                subject,
                from_email,
                kwargs.get('to'),
                headers=headers
            )

        message.attach_alternative(body, 'text/html')
        message.send(fail_silently=False)

Then, when you want to send an email you use the send_html_email method:

# views.py
...
data = {
          'from_email': 'my_email@whatever.com',
          'subject': 'My pretty subject',
          'to': ['recipient@email.com', ],
          'template_name': 'templates_dir/my_html_message.html',
          'context': {'name': 'Name of user', 'money': 1000},
        }

Email.send_html_email(**data)
...
Gocht
  • 9,924
  • 3
  • 42
  • 81
  • thank you @Gocht but actually your answer is for older (then 1.7) Django version – user123892 Nov 20 '15 at 15:11
  • @user123892 I use this code in a Django 1.8 project, Whant changed is that now you can define `reply-to` header as a parameter. – Gocht Nov 20 '15 at 15:15
  • 1
    sorry @Gocht I did not mean your solution does not work, but that I wanted to use the new parameter html_message provided in send_mail() from Django 1.7 (https://docs.djangoproject.com/en/1.8/topics/email/#send-mail) – user123892 Nov 20 '15 at 15:37