Question or problem about Python programming:
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.
How to solve the problem:
Solution 1:
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 ' 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:
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:
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 4:
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:
... content ...
More details here: Send alternative content types from django docs
Solution 5:
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:
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 =
Hello.. {{ first_name }} {{ last_name }}.
This is an important {{ message }}
By Admin.
Good Day
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:
from django.core.mail import EmailMultiAlternatives subject, from_email, to = 'hello', '[email protected]', '[email protected]' text_content = 'This is an important message.' html_content = '
This is an important message.' msg = EmailMultiAlternatives(subject, text_content, from_email, [to] msg.attach_alternative(html_content, "text/html") msg.send()