How to send html email with django with dynamic content in it?

PythonDjango

Python Problem Overview


Can anyone please help me sending html email with dynamic contents. One way is to copy the entire html code into a variable and populate the dynamic code within it in Django views, but that does not seem to be a good idea, as its a very large html file.

I would appreciate any suggestions.

Thanks.

Python Solutions


Solution 1 - Python

Django includes the django.core.mail.send_mail method these days (2018), no need to use EmailMultiAlternatives class directly. Do this instead:

from django.core import mail
from django.template.loader import render_to_string
from django.utils.html import strip_tags

subject = 'Subject'
html_message = render_to_string('mail_template.html', {'context': 'values'})
plain_message = strip_tags(html_message)
from_email = 'From <[email protected]>'
to = '[email protected]'

mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

This will send an email which is visible in both html-capable browsers and will show plain text in crippled email viewers.

Solution 2 - Python

Example:

from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils.html import strip_tags

subject, from_email, to = 'Subject', '[email protected]', '[email protected]'

html_content = render_to_string('mail_template.html', {'varname':'value'}) # render with dynamic value
text_content = strip_tags(html_content) # Strip the html tag. So people can see the pure text at least.

# create the email, and attach the HTML version as well.
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()

Solution 3 - Python

For anyone looking at this in 2020 and using django v3.x (I don't know when this was introduced so it might work for earlier versions.

Note: I only wanted to include an html version without a plain text version. My django view:

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

# import html message.html file
html_template = 'path/to/message.html'

html_message = render_to_string(html_template, { 'context': context, })

message = EmailMessage(subject, html_message, from_email, [to_email])
message.content_subtype = 'html' # this is required because there is no plain text email message
message.send()

My html file (message.html) looked like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Order received</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body style="margin: 0; padding: 0;">
  <table align="center" border="0" cellpadding="0" cellspacing="0" width="320" style="border: none; border-collapse: collapse; font-family:  Arial, sans-serif; font-size: 14px; line-height: 1.5;">
...
content
...
</table>
</body>
</html>

More details here: Send alternative content types from django docs

Solution 4 - Python

This should do what you want:

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


template = get_template('myapp/email.html')
context = Context({'user': user, 'other_info': info})
content = template.render(context)
if not user.email:
    raise BadHeaderError('No email address given for {0}'.format(user))
msg = EmailMessage(subject, content, from, to=[user.email,])
msg.send()

See the django mail docs for more.

Solution 5 - Python

Try this::::

https://godjango.com/19-using-templates-for-sending-emails/

sample code link

# views.py

from django.http import HttpResponse
from django.template import Context
from django.template.loader import render_to_string, get_template
from django.core.mail import EmailMessage

def email_one(request):
    subject = "I am a text email"
    to = ['[email protected]']
    from_email = '[email protected]'

    ctx = {
        'user': 'buddy',
        'purchase': 'Books'
    }

    message = render_to_string('main/email/email.txt', ctx)

    EmailMessage(subject, message, to=to, from_email=from_email).send()

    return HttpResponse('email_one')

def email_two(request):
    subject = "I am an HTML email"
    to = ['[email protected]']
    from_email = '[email protected]'

    ctx = {
        'user': 'buddy',
        'purchase': 'Books'
    }

    message = get_template('main/email/email.html').render(Context(ctx))
    msg = EmailMessage(subject, message, to=to, from_email=from_email)
    msg.content_subtype = 'html'
    msg.send()

    return HttpResponse('email_two')

Solution 6 - Python

If you want dynamic email templates for your mail then save the email content in your database tables. This is what i saved as HTML code in database =

<p>Hello.. {{ first_name }} {{ last_name }}.  <br> This is an <strong>important</strong> {{ message }}
<br> <b> By Admin.</b>

 <p style='color:red'> Good Day </p>

In your views:

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

def dynamic_email(request):
    application_obj = AppDetails.objects.get(id=1)
    subject = 'First Interview Call'
    email = request.user.email
    to_email = application_obj.email
    message = application_obj.message

    text_content = 'This is an important message.'
    d = {'first_name': application_obj.first_name,'message':message}
    htmly = FirstInterviewCall.objects.get(id=1).html_content #this is what i have saved previously in database which i have to send as Email template as mentioned above HTML code

    open("partner/templates/first_interview.html", "w").close() # this is the path of my file partner is the app, Here i am clearing the file content. If file not found it will create one on given path.
    text_file = open("partner/templates/first_interview.html", "w") # opening my file
    text_file.write(htmly) #putting HTML content in file which i saved in DB
    text_file.close() #file close

    htmly = get_template('first_interview.html')
    html_content = htmly.render(d)  
    msg = EmailMultiAlternatives(subject, text_content, email, [to_email])
    msg.attach_alternative(html_content, "text/html")
    msg.send()

This will send the dynamic HTML template what you have save in Db.

Solution 7 - Python

from django.core.mail import EmailMultiAlternatives

subject, from_email, to = 'hello', '[email protected]', '[email protected]'
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()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnkit JaiswalView Question on Stackoverflow
Solution 1 - PythonBabken VardanyanView Answer on Stackoverflow
Solution 2 - PythonMarvin WView Answer on Stackoverflow
Solution 3 - PythonalkadelikView Answer on Stackoverflow
Solution 4 - PythonblokeleyView Answer on Stackoverflow
Solution 5 - PythonvijayView Answer on Stackoverflow
Solution 6 - PythonJavedView Answer on Stackoverflow
Solution 7 - PythonHamdi HassenView Answer on Stackoverflow