How do I disable Django's autoescape from a vi

2019-06-27 04:24发布

问题:

Django says there's 3 ways to turn off autoescape:

  1. Use |safe after the variable
  2. Use {% autoescape on %} and {% endautoescape %} within blocks
  3. Use a Context like context = Context({'message': message}, autoescape=False)

(1) and (2) work fine. But I have the situation where I have templates to generate plain-text push notifications, and I have LOADS of templates to build and maintain. I could go through and put the {% autoescape on %} and {% endautoescape %} tags in all of them, but (3) should allow me to do it in one line in the view.

The template:

{% block ios_message %}{{message}}{% endblock %}

The view:

message = u"'&<>"
context = Context({'message': message}, autoescape=False)
render_block_to_string(template_name, 'ios_message', context)

The output:

u'&#39;&amp;&lt;&gt;

The code for block_render.py is from here: https://github.com/uniphil/Django-Block-Render/blob/master/block_render.py. I'm using it as is from there.

Anyone know what gives?

回答1:

Take a closer look to function render_block_to_string():

def render_block_to_string(template_name, block, dictionary=None,
                           context_instance=None):
    """Return a string

    Loads the given template_name and renders the given block with the
    given dictionary as context.

    """
    dictionary = dictionary or {}
    t = _get_template(template_name)
    if context_instance:
        context_instance.update(dictionary)
    else:
        context_instance = Context(dictionary)
    return render_template_block(t, block, context_instance)

The 3rd arg should be a dict, not context. Otherwise it would use the normal context instance.

So I believe it should be:

render_block_to_string(template_name, 'ios_message', {},  context)

Hope it helps.



回答2:

I could solve it my doing it like that:

from django.template.context import make_context
from django.template.loader import get_template

# Getting the template either by a path or creating the Template object yourself
template = get_template('your/path/to/the/template.html')
# Note here the 'template.template' and the 'autoescape=False' parameter
subject = template.template.render(make_context(context, autoescape=False))

Found it by doing that myself. Because by default the autoescape setting will be used from the engine https://github.com/django/django/blob/4b6dfe16226a81fea464ac5f77942f4d6ba266e8/django/template/backends/django.py#L58-L63

Django Version: 2.2.1