7👍
bar = json.dumps(foo, ensure_ascii=False)
will result in bar
being a unicode
object; without ensure_ascii=False, bar
is a str
.
Django’s smart_text method might also be useful for conversions.
4👍
<div id="foobar">{{ foobar }}</div>
will display the unicode string as byte string:
{ "name":"\u8d5e\u4e00\u4e0b\u6211\u4eec" }
This is displaying the whole object in its JSON-encoded form. Whilst you could use json.dumps(..., ensure_ascii=False)
to keep non-ASCII characters like the Chinese in their raw form rather than encoded into ASCII-safe-JSON, this would still give you {"name": "赞一下我们"}
which is probably not what you want.
If you only want the name
property of the object included in the div, you will need to pass the item foo['name']
to your template – or the whole of foo
and have the template include {{foo.name}}
– rather than including the whole encoded JSON object from foobar
.
foobar=JSON.encode('{{foobar|safe}}');
There is no method encode
on the ECMA standard JSON
object, so I don’t know what that’s doing.
The JSON-encoding method is JSON.stringify
. But you don’t want to encode here – you already have a string with a JSON representation of an object here because you encoded it above at the server side in the call to json.dumps
. Probably you meant:
var foobar = JSON.parse('{{foobar|safe}}');
which would work for your particular value of name
, but not necessarily in general. For example if the name was a\nb
then you would get:
JSON.parse('{"name": "a\nb"}')
in which case the \n
would get parsed by the JavaScript interpreter as being a newline character in the string, and so the string parsed as JSON would be:
{"name": "a
b"}
which is a syntax error. There are also security issues here – contrary to the |safe
assertion, this is not safe. If the name
property contained the string </script
then you would end up with a prematurely-ended script element, which can lead to cross-site scripting attacks:
<script>
var foobar = JSON.parse('</script>
<script>alert();//attacker code here');</script>
You could attempt to get around these by doing a second layer of JS string literal encoding on the JSON at the server side, and manually replace <
with \u003C
. But probably it’s best to take a different approach – generating executable code on the fly is fraught with problems in general, especially when you have multiple different syntaxes in the mix (Python/Django-template, HTML and JS/JSON).
If you write data to the document (for example in a data-
attribute) rather than the script then you can keep the normal and safe template behaviour of HTML-escaping. Then the JS side can read the data out of the DOM. For example:
<div id="foobar" data-foobar="{{ foobar }}">
...
var foobar = $('#foobar').data('foobar');
(jQuery’s data
method implicitly does the JSON.parse
for you.)
This helps with separation of concerns, getting JS out into external scripts, and potentially eventually using Content-Security-Policy.
- [Django]-Celery: running a worker with superuser privileges
- [Django]-Exception Value: context must be a dict rather than WSGIRequest
- [Django]-My custom heroku python buildpack downloads requirements on every push
1👍
You need to reference the element within the dict, without JSON-encoding it.
return render_to_response(..., {..., 'foo': foo}, ...)
…
{{ foo.name }}
- [Django]-Django-mptt filter without breaking the tree
- [Django]-Monitoring django postgres connections