Sending HTML emails with embedded images from Django

JunePyo Suh·2020년 9월 22일
0

Code examples adopted from this blog

HTML template code

<!-- BODY -->
<table class="body-wrap">
    <tr>
        <td></td>
        <td class="container" bgcolor="#FFFFFF">
             <div class="content">
                <table>
                    <tr>
                        <td>
                            {% for view in views %}
                                <h3>{{ view }}</h3>
                                <p><img src="cid:{{ view.image_filename }}" /></p>
                                {% if not forloop.last %}<p>&nbsp;</p>{% endif %}
                            {% endfor %}
                        </td>
                    </tr>
                </table>
            </div>
        </td>
        <td></td>
    </tr>
</table><!-- /BODY -->

Image table will be rendered as such:

<img src="cid:20161010_dailykpisnapshot_OCuZ4O4.png">

Views.py

import os
from email.mime.image import MIMEImage

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


rendered_report = RenderedReport.objects.get(pk=1)
views = rendered_report.rendered_views.all()

context = {'views': views}

html_content = render_to_string('reports/email.html', context=context).strip()

subject = 'HTML Email'
recipients = ['john.doe@test.com']
reply_to = ['noreply@test.com']

msg = EmailMultiAlternatives(subject, html_content, config.formatted_email_from, to, reply_to=reply_to)
msg.content_subtype = 'html'  # Main content is text/html
msg.mixed_subtype = 'related'  # This is critical, otherwise images will be displayed as attachments!

for view in views:
    # Create an inline attachment
    image = MIMEImage(view.png.read())
    image.add_header('Content-ID', '<{}>'.format(view.image_filename))
    msg.attach(image)

    # Create a regular attachment with a CSV file
    if view.csv:
        filename = os.path.basename(view.csv.name)
        msg.attach(filename, view.csv.read(), 'text/csv')

    # Create a regular attachment with a PDF file
    if view.pdf:
        filename = os.path.basename(view.pdf.name)
        msg.attach(filename, view.pdf.read(), 'application/pdf')

msg.send()

Email headers will look like this:

Content-Type: image/png
Content-Disposition: inline
Content-Transfer-Encoding: base64
Content-ID: <20161010_dailykpisnapshot_OCuZ4O4.png>

In production

In production it may be better to reference the image from your S3 source. In this case, no other backend work is needed in views.py, and simply include the S3 url of the target image.

0개의 댓글