Search code examples
pythonhtmldjangorender-to-string

Django autoescape is not working in render_to_string(template)?


I am drafting an email template to users when they successfully updated their passwords.

I used {{ autoescape off }} in the template, which is rendered by using render_to_string().

However, the email content shows the HTML angle brackets directly like this:

Hi <span style='color:blue'>user! </span>

Your password is updated successfully!


I am using Django2.0 and my code looks like this:

views.py

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

def sendmail(request, title)
    email_title = title
    email_content = render_to_string('template.html',{'username':request.user.username})
    recipient = request.user.email
    send_mail(
            email_title,
            email_content,
            '[email protected]',
            [recipient,],
            )

template.html

{{ autoescape off}}
Hi <span style='color:blue'>user! </span>
Your password is updated successfully!
{{ endautoescape }}

Is there anything wrong with my code?

Otherwise, is autoescape always on while using render_to_string()?


Solution

  • This has nothing to do with autoescape, which is for rendering variables (it is also a template tag, so you use it with {% autoescape off %}, not {{ autoescape off }}). It is doing nothing at all in your current template.

    Your issue is that you're trying to put HTML into the plain text body of an email.

    send_mail expects a plain text message body. If you want to have a HTML body then you need to supply a html_message argument:

    send_mail(
        email_title,
        '',  # Empty plain text body - not recommended and you should supply a plain text alternative
        '[email protected]',
        [recipient,],
        html_message=email_content,  # This will render as HTML
    )