1👍
I think you need to pass it through the safe
filter if you want the raw string:
{{ result.dat|safe }}
You can also use the {% autoescape off %}
block if you want to affect a larger block of the template.
0👍
var dat = {{ result.dat }}
You’re trying to inject into JavaScript, presumably in a <script>
block. You need output that is formatted in JavaScript syntax, but you’re implicitly converting a Python list to a string, which will give a Python-syntax list literal, not a JavaScript one. There are a number of differences, including text (Unicode) strings in the list being prefixed with u
in Python 2 but not JS.
You’re also using the default autoescaping for Django templates, which is HTML-escaping. That would be right for injecting into HTML content, but you’re injecting into JavaScript, so you get wrong escapes like '
for '
. You can prevent this by adding the |safe
filter to avoid the HTML-escaping, but then you have no escaping at all, so your page will be vulnerable to script injection (cross-site scripting).
The right way to output a structured value into a <script>
block is:
json.dumps
to turn it into a JSON string- replace any instances of the character
<
in the string with the JSON string literal escape\u003C
, so that the string</script>
can’t be used to escape from the<script>
block and inject HTML - mark as safe.
You can combine these operations into a custom filter. Unfortunately Django itself doesn’t ship one.
A better approach is to avoid injecting into JavaScript at all. Instead write the json.dumps
output into the HTML document using the standard escaping and read it from there using DOM:
return render(request, 'result_map.html', {'form': form, 'dat': json.dumps(dat)})
...
<body data-dat="{{ dat }}">
...
var dat= JSON.parse(document.body.getAttribute('data-dat'));
this allows you to keep your JS completely out of your HTML pages, which would also allow you to use more secure Content-Security-Policy
settings.