38

Django templating system provides a few options (filters) for escaping contents in the html, but they are kind of confusing to me as a beginner. Say I'm following a tutorial to make a simple blog, and the blog content needs to be escaped - I trust the content because I am the only one editing it. So the question is should I do it like {{ post.content|autoescape }}, {{ post.content|escape }}, or {{ post.content|safe }} in the html?

Thanks

EDIT: Which filter should I use to have special characters converted to html entities automatically?

EDIT 2: I just realized that autoescape is not a valid filter.

vishes_shell
  • 22,409
  • 6
  • 71
  • 81
user14412
  • 987
  • 1
  • 11
  • 32

4 Answers4

53

HTML escaping is on by default in Django templates.

Autoescape is a tag. not a filter:

{% autoescape on %}
    {{ post.content }}
{% endautoescape %}

The 'escape' filter escapes a string's HTML. Specifically, it makes these replacements:

  • < is converted to &lt;
  • > is converted to &gt;
  • ' (single quote) is converted to &#39;
  • " (double quote) is converted to &quot;
  • & is converted to &amp;

The 'force_escape' is almost identical to 'escape' except for a few corner cases.

The 'safe' filter will mark your content as safe, so it won't be escaped (will be sent to browser as is).

Which filter should I use to have special characters converted to html entities automatically?

Well, you mean, like converting à to &Atilde;? Stick with utf-8 encoding all the way and forget about those.

Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
  • 1
    Very helpful listing the characters. Does this 'escape' filter work for _both_ HTML element text and attribute values? e.g. `{{ text }}` – Bob Stein Jan 05 '16 at 16:13
  • @BobStein-VisiBone I guess it work everywhere, but I'm not sure I understood your question. Sometimes it is better to post a new question because it is more likely to help others with the same doubts. – Paulo Scardine Jan 06 '16 at 11:51
  • 10
    @BobStein-VisiBone on place where the escape filter may not work well is inside ``, in this case use `{{ value|escapejs }}` – Paulo Scardine Jan 06 '16 at 13:24
  • The script/escapejs point is very helpful. I was concerned about different escaping needs for HTML attribute values (between the quotes) versus HTML element contents (outside the angle brackets). `"` and `'` should cover the quotes. I thought I read long ago that attribute values shouldn't contain line terminators, but can't find that now. – Bob Stein Jan 06 '16 at 20:56
  • @BobStein-VisiBone to my knowledge line terminators inside attributes are legal, verbatim. You may have read about [XML attribute normalization](http://www.w3.org/TR/REC-xml/#AVNormalize) or something like that. – Paulo Scardine Jan 07 '16 at 07:43
  • Right you are, it was an [XHTML thing](http://www.w3.org/TR/xhtml1/guidelines.html#C_5). "Avoid line breaks and multiple white space characters within attribute values." Glad that's over. – Bob Stein Jan 07 '16 at 14:06
29

first of all, you should escape your content because you never know (even if you are the one who enter the data) if you are going to need special character (like <, >, ).

The syntax you use show you are uncomfortable with the use of escaping :

this

{% autoescape on %}
    {{ content }}
{% endautoescape %}

is exactly the same as this

{{ content|escape }}

this

{{ content }}

is exactly the same as this <-- edit : If the autoescape is OFF (thanks to Paulo Scardine)

{{ content|safe }} 

Safe is use like that :

{% autoescape on %}
    {{ content }}  <-- escape
    {{ content|safe }}  <-- not escape
{% endautoescape %}
BlueMagma
  • 2,392
  • 1
  • 22
  • 46
11

Your question shows you are a little confused about what escaping is.

Escaping is turning non-safe characters - like HTML tags - into escaped versions so that malicious content such as script tags don't ruin your site. Django does this by default on all content rendered in a template from a variable.

It seems by your comment that you're the only one editing your content that what you want is to render your variables without the automatic escaping. So, for that, you need to mark it as safe. You can either do this in the template, by either wrapping the whole lot in {% autoescape off %}...{% endautoescape %} tags or via the {{ myvar|safe }} filter on individual variables. Or, you can do it in the view, by calling mark_safe(myvar) on individual variables before passing them to the template.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks for your answer. I'm actually trying to escape the contents rather than marking them as safe. I thought the safe filter means to make the contents safe... – user14412 Jul 03 '12 at 08:41
0

To avoid escaping use "safe" (https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#safe):

Marks a string as not requiring further HTML escaping prior to output. When autoescaping is off, this filter has no effect.

To escape use "escape" (https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#escape):

Escapes a string's HTML.

Tadeck
  • 132,510
  • 28
  • 152
  • 198