How to Send an Email with an Inline Image in Django

In this article, we show to send an email with an inline image in Django.
When you're building a website, many times, it's not simply good enough to send plain text in an email. Many times, we want to add images.
We cannot simply use the Django send_mail() function to do this. It works with plain text and doesn't render images in an email.
Instead, you must use the EmailMultiAlternatives() function. This function will allow for proper rendering of inline images in an email.
Below is a sample code that sends an email with an inline image in
Django.
Just like the send_email() function, this function takes in the subject (or title) of the email, the body, the sender email, and the email that you are sending to.
MIME stands for Multipurpose Internet Mail Extensions. It's an internet standard that defines how email messages are formatted when they contain data other than ASCII character sets. MIME is an extension of the Simple Mail Transport Protocol (SMTP) email protocol, and it allows users to exchange different types of data files in their emails, including images, audio, video, and application programs.
This is exactly what we are looking to do with an image in our text.
Though you can also add audio or video to an email, this is much less done than with images, which are common in business email marketing campaigns.
Though the MIME tpe of the body parameter in an email message is "text/plain" unless otherwise specified, when sending complex message such as HTML, this type should be changed to "text/html". If sending a simple message, it is good practice to leave it as "text/plain" because it guarantees that any recipient will be able to read the email, regardless of their mail client. However, if you are sure that your recipients can take in an alternative content type or you're sending a complex email with HTML and images, you must use "text/html". If not, the HTML tags will not be rendered; you'll have HTML tags show up in the email unrendered, along with no images showing.
An important concept of images not showing is that it must be specified within the code, message.mixed_subtype = 'related'
One big problem with images not displaying with Django is because the EmailMessage (and EmailMultiAlternatives) classes in Django use "multipart/mixed" content type for the message, when in fact you need "multipart/related".
So this line must be specified for images to render properly.
How we specify that we want the HTML in our email to be rendered is through the line, message.content_subtype = 'html'
Of course the major type will always be 'text', but by specifying that the content_subtype is 'html', we allow for HTML tags to be rendered.
And next, we simply just send the email out with the send() function.
Below is such an email sent in Django using the EmailMultiAlternatives() with its corresponding attributes.
This is all that is required to send an email in Django that renders
HTML and inline images, giving emails a great, professional look.
Related Resources
How to Randomly Select From or Shuffle a List in Python