Django email message as HTML - html

I have an email template that I use to send emails of different kinds. I'd rather not keep multiple email HTML templates, so the best way to handle this is to customize the message contents. Like so:
def email_form(request):
html_message = loader.render_to_string(
'register/email-template.html',
{
'hero': 'email_hero.png',
'message': 'We\'ll be contacting you shortly! If you have any questions, you can contact us at meow#something.com',
'from_email': 'lala#lala.com',
}
)
email_subject = 'Thank you for your beeswax!'
to_list = 'johndoe#whatever.com'
send_mail(email_subject, 'message', 'from_email', [to_list], fail_silently=False, html_message=html_message)
return
When the email is sent however, the html codes don't work. The message appears as it is exactly, angled brackets and all. Is there a way for me to force it to render as HTML tags?

Use EmailMessage to do it with less trouble:
First import EmailMessage:
from django.core.mail import EmailMessage
Then use this code to send html email:
email_body = """\
<html>
<head></head>
<body>
<h2>%s</h2>
<p>%s</p>
<h5>%s</h5>
</body>
</html>
""" % (user, message, email)
email = EmailMessage('A new mail!', email_body, to=['someEmail#gmail.com'])
email.content_subtype = "html" # this is the crucial part
email.send()

Solved it. Not very elegant, but it does work. In case anyone's curious, the variable placed in the email template should be implemented as so:
{{ your_variable|safe|escape }}
Then it works! Thanks guys!

You can use EmailMultiAlternatives feature present in django instead of sending mail using send mail. Your code should look like the below snipet.
from django.core.mail import EmailMultiAlternatives
def email_form(request):
html_message = loader.render_to_string(
'register/email-template.html',
{
'hero': 'email_hero.png',
'message': 'We\'ll be contacting you shortly! If you have any questions, you can contact us at meow#something.com',
'from_email': 'lala#lala.com',
}
)
email_subject = 'Thank you for your beeswax!'
to_list = 'johndoe#whatever.com'
mail = EmailMultiAlternatives(
email_subject, 'This is message', 'from_email', [to_list])
mail.attach_alternative(html_message, "text/html")
try:
mail.send()
except:
logger.error("Unable to send mail.")

Related

django admin send email to user

\admin.py
#admin.register(ParentsProfile)
class ParentsProfile(admin.ModelAdmin):
list_display = ('Father_Email','Fathers_Firstname' , 'Fathers_Middle_Initial', 'Fathers_Lastname', 'Request')
ordering = ('Request',)
search_fields = ('Request',)
actions = ['Send_Email','Send_Email_Disapproved']
def Send_Email(self, request, queryset):
html_content = "Your Registration has been approved.\n\nPlease use this %s as your username and %s as your password. \nYou may now start enrolling your student using this link https://...../Plogin_form/ \n\n\n REGISTRAR "
for profile in queryset:
send_mail(subject="Invite", message=html_content %(profile.Father_Email,profile.Parent_Password), from_email=settings.EMAIL_HOST_USER,
recipient_list=[profile.Father_Email]) # use your email function here
def Send_Email_Disapproved(self, request, queryset):
# the below can be modified according to your application.
# queryset will hold the instances of your model
for profile in queryset:
send_mail(subject="Invite", message="Our Apology,\n\n Your Registration has been Disapproved " + profile.Father_Email + "\n\n\n REGISTRAR" + "", from_email=settings.EMAIL_HOST_USER,
recipient_list=[profile.Father_Email])
i have this code to send an email to user, how do i convert my html_content into HTML? so that i can design my message to user?
it send to user gmail like this,
You can render it with django.template.loader.render_to_string
You first need to store your template in your template folder, for example:
<!-- your_app/templates/my_template.html -->
<h1>hello, {{ user.first_name }}</h1>
Then in your code, change the html_content to
html_content = render_to_string('my_template.html', {
'user': User.objects.get(username="some_username")
})
Doc: https://docs.djangoproject.com/en/2.2/topics/templates/#django.template.loader.render_to_string

Django send an email on post_save with templates

I'm attempting to send an email our admin when new data is submitted to our website from the users. We are using a Django for the backend and Vue for the front end, even though that probably doesn't matter. Here is the code:
#receiver(post_save)
def send_update(sender, created, **kwargs):
if created:
data=kwargs['instance']
try:
if data.admin_approved == False:
print("point 1 reached")
name = data.submitted_by_name
body = data.body
content_type = str(sender).split(".")[2][:-2]
print("point 2 reached")
link = "https://link_to_website.com" + content_type.lower()
subject = "New " + content_type + " submitted"
print("point 3 reached")
from_email = "NoReply#web_site.com"
to_email = "my_email#address.com"
print("pre-html point reached")
html_message = get_template('./email/template.html')
text_message = get_template('./email/textplate.txt')
data = {
'user_name': name,
'submission': data.body,
'type': content_type,
'link': link,
'body': body
}
content_text = text_message.render(data)
content_html = html_message.render(data)
print("ready to send email!")
msg = EmailMultiAlternatives(subject, content_text, from_email, [to_email])
msg.attach_alternative(content_html, "text/html")
msg.send()
except:
print("Data was not submitted by an non-admin user.")
The try/except is included so that data that is submitted directly through the django admin page does not trigger the email function.
the function works up until "pre-html point reached", I'm guessing the issue is somewhere within the msg and msg.send() but I am not receiving any error functions.
Thanks for the help!

Login to https website with Python with request

I'd like to access some content from https://bato.to/ that requires me to login first. Their login page is: https://bato.to/forums/index.php?app=core&module=global&section=login
I've opened chrome's web developer tools to inspect the POST that's sent when I click login. The 'Form Data' inside the POST is:
auth_key:880ea6a14ea49e853634fbdc5015a024
referer:https://bato.to/forums/
ips_username:startwinkling
ips_password:password1
rememberMe:1
So I've tried to implement this with the code:
Code so far
from requests import session
import re
AUTH_KEY = re.compile(r"<input type='hidden' name='auth_key' value='(.*?)' \/>")
payload = {
'ips_username': 'startwinkling',
'ips_password': 'password1',
'rememberMe' : '1',
'referer' : 'https://bato.to/forums/'
}
with session() as c:
login_url = 'https://bato.to/forums/index.php?app=core&module=global&section=login'
page = c.get(login_url)
auth_key = AUTH_KEY.search(page.text).group(1)
payload['auth_key'] = auth_key
print("auth_key: %s" % auth_key)
page = c.post(login_url, data=payload)
page = c.get('https://bato.to/reader#4b57865eb3a9a9a6')
print(page.text)
I believe I'm grabbing and passing in the auth_key properly since the code outputs:
auth_key: 880ea6a14ea49e853634fbdc5015a024
But the HTML that's printed out indicate that I haven't been able to successfully log in. What am I missing here?
The URL you use for POST is not correct.
The correct one should be https://bato.to/forums/index.php?app=core&module=global&section=login&do=process, it's not the same as login landing page, notice the extra do=process part.
Codes:
from requests import session
import re
AUTH_KEY = re.compile(r"<input type='hidden' name='auth_key' value='(.*?)' \/>")
payload = {
'ips_username': 'startwinkling',
'ips_password': 'password1',
'rememberMe' : '1',
'referer' : 'https://bato.to/forums/'
}
with session() as c:
login_url = 'https://bato.to/forums/index.php?app=core&module=global&section=login'
page = c.get(login_url)
auth_key = AUTH_KEY.search(page.text).group(1)
payload['auth_key'] = auth_key
print("auth_key: %s" % auth_key)
page = c.post(login_url + '&do=process', data=payload)
page = c.get('https://bato.to/reader#4b57865eb3a9a9a6')
print(page.text)
P.S. I would suggest you to add some headers(not use default headers) as well, you might not want to appear as User-Agent: python-requests/1.2.3 CPython/2.7.3 Windows/7 on their analytics, also in case they set some limits on certain pages for "non-browser" visit.

Django/Python: views.py and passing strings of text

So in my template, I have the following code:
<span class="state-txt">{{ state }}</span>
In my views.py, it's handled with the following if/else loop:
if user is not None:
if user.is_active:
login(request, user)
state = "You're successfully logged in!"
return render_to_response('uc/portal/index.html', {'state':state, 'username':username}, context_instance=RequestContext(request))
else:
state = "Your account is not active, please contact UC admin."
else:
state = "Your username and/or password were incorrect."
Essentially, it's working fine at the moment but I want each state to be able to contain different <img> tags, but when I just type state = "<img src="some.jpg"> Your username and/or password were incorrect." The html doesn't render correctly. Is there some way to do what I'm trying to do in Django, or am I barking up the wrong tree?
I would just pass the image URL in the context from the view, and consume that in the template. Something like this:
if user:
if user.is_active:
login(request, user)
state = "You're successfully logged in!"
state_img = success_image_url
return render_to_response('uc/portal/index.html',
{'state': state,
'state_img': state_img,
'username':username
}, context_instance=RequestContext(request))
else:
state_img = inactive_image_url
state = "Your account is not active, please contact UC admin."
else:
state_img = invalid_credentials_url
state = "Your username and/or password were incorrect."
and in the template
<span class="state-txt">
<img src="{{state_img}}" />{{ state }}
</span>
For completeness' sake, as karthikr already posted an excellent solution:
The reason the html doesn't render correctly, is because the Django template language automatically assumes that all output by {{ ... }} is not safe, all symbols that have a special meaning in HTML will be escaped (< becomes < etc.).
To render a string as pure HTML code, use the safe filter.
views.py:
state = "<img src="some.jpg" /> Your username and/or password were incorrect."
index.html:
<span class="state-txt">{{ state|safe }}</span>
Don't render the image. try if else
view.py
if user is not None:
if user.is_active:
login(request, user)
state = True
return render_to_response('uc/portal/index.html', {'state':state, 'username':username}, context_instance=RequestContext(request))
else:
state = False
else:
state = False
in template
{%if state %}
<img></img>
you are successfully logged in.
{%endif%}

How to setup send HTML email with mail gem?

I am sending email using the Mail gem. Here's my code:
require 'mail'
require 'net/smtp'
Mail.defaults do
delivery_method :smtp, { :address => "smtp.arrakis.es",
:port => 587,
:domain => 'webmail.arrakis.com',
:user_name => 'myname#domain.com',
:password => 'pass',
:authentication => 'plain',
:enable_starttls_auto => true }
end
Mail::ContentTypeField.new("text/html") #this doesnt work
msgstr= File.read('text2.txt')
list.each do |entity|
begin
Mail.deliver do
from 'myname#domain.com'
to "#{entity}"
subject 'a good subject'
body msgstr
end
rescue => e
end
end
end
I don't know how to set up the content type, so that I can format my email as html for example. Though I actually just wish to be able to define bold text like my email client does: bold text. Does anybody know which content-type I need to specify in order to achieve this, and how to implement it with mail?
Just a note, the code above works fine for sending plain text email.
From the documentation
Writing and sending a multipart/alternative (html and text) email
Mail makes some basic assumptions and makes doing the common thing as
simple as possible.... (asking a lot from a mail library)
mail = Mail.deliver do
to 'nicolas#test.lindsaar.net.au'
from 'Mikel Lindsaar <mikel#test.lindsaar.net.au>'
subject 'First multipart email sent with Mail'
text_part do
body 'This is plain text'
end
html_part do
content_type 'text/html; charset=UTF-8'
body '<h1>This is HTML</h1>'
end
end
#Simone Carletti's answer is essentially correct, but I was struggling with this and didn't want a plain text portion to my email and a separate HTML portion. If you just want the entire email to be HTML, something like this will work:
mail = Mail.deliver do
to 'nicolas#test.lindsaar.net.au'
from 'Mikel Lindsaar <mikel#test.lindsaar.net.au>'
subject 'First email sent with Mail'
content_type 'text/html; charset=UTF-8'
body '<h1>This is HTML</h1>'
end
I may have missed it, I didn't see anything in the Mail gem documentation describing how to do that, which I would think would be more common than making a multipart message. The documentation only seems to cover plain text messages and multipart messages.