Code examples adopted from this blog
<!-- 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> </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">
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 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.