Python 将 JSON 数组从 Django 视图返回到模板
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15592811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning JSON array from a Django view to a template
提问by DefPlayr
I'm using Django to create a web-based app for a project, and I'm running into issues returning an array from a Django view to a template.
我正在使用 Django 为项目创建基于 Web 的应用程序,但在将数组从 Django 视图返回到模板时遇到了问题。
The array will be used by a JavaScript (JQuery) script for drawing boxes on an image shown in the page. Therefore, this array will have, among other things, coordinates for the boxes to be drawn.
JavaScript (JQuery) 脚本将使用该数组在页面中显示的图像上绘制框。因此,该数组将包含要绘制的框的坐标。
This is the code in the Django view used to get the required data and serialize it as JSON:
这是 Django 视图中用于获取所需数据并将其序列化为 JSON 的代码:
def annotate(request, ...):
...
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
tags = serializers.serialize("json", oldAnnotations)
...
return render_to_response('vannotate.html', {'tags': tags, ...})
As a way of debugging, using {{ tags }}in the HTML portion of the template gives this as output (sorry for the long line):
作为调试的一种方式,{{ tags }}在模板的 HTML 部分中使用将其作为输出(对不起,很长的一行):
[{"pk": 491, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 220, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 242}}, {"pk": 492, "model": "va.videoannotation", "fields": {"ParentVideoFile": 4, "ParentVideoFrame": 201, "ParentVideoLabel": 4, "top": 218, "height": 30, "width": 30, "ParentVideoSequence": 16, "left": 307}}]
which I assume is the correct format for a JSON array.
我认为这是 JSON 数组的正确格式。
Later on in the template, I attempt to actually use the tagsvariable in the JavaScript portion of the template, as follows:
稍后在模板中,我尝试实际使用tags模板的 JavaScript 部分中的变量,如下所示:
{% if tags %}
var tagbs = {{ tags|safe }};
var tgs = JSON.parse(tagbs);
alert("done");
{% endif %}
If I remove the var tgs = JSON.parse(tagbs);line, then the alert box pops up fine, and the rest of the JavaScript works as expected. Leaving this line in breaks the script, however.
如果我删除该var tgs = JSON.parse(tagbs);行,则警告框会正常弹出,其余的 JavaScript 会按预期工作。但是,保留这一行会破坏脚本。
I want to be able to iterate through all the objects in the Django model and get values of fields in JavaScript.
我希望能够遍历 Django 模型中的所有对象并获取 JavaScript 中的字段值。
I'm not sure what I'm doing wrong here, could someone point out the right way to do this?
我不确定我在这里做错了什么,有人可以指出正确的方法吗?
采纳答案by user9876
Edit with update for Django 2.1+ and the modern web:
使用 Django 2.1+ 和现代网络的更新进行编辑:
The modern way to do this is:
现代方法是:
1) Pass the raw data to the template, not the JSON-serialised data. I.e.:
1) 将原始数据传递给模板,而不是 JSON 序列化的数据。IE:
def annotate(request, ...):
...
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
...
return render_to_response('vannotate.html', {'tags': oldAnnotations, ...})
2) In your template, use the new "json_script" filter to include the JSON data:
2) 在您的模板中,使用新的“json_script”过滤器来包含 JSON 数据:
{{ tags|json_script:"tags-data" }}
That will result in HTML that looks like this:
这将导致 HTML 如下所示:
<script id="tags-data" type="application/json">{"foo": "bar"}</script>
This tag has special handling of strings containing "</script>" to make sure they work.
该标签对包含“</script>”的字符串进行了特殊处理,以确保它们正常工作。
3) In your Javascript code, get that tags data like this:
3) 在您的 Javascript 代码中,像这样获取标签数据:
var tags = JSON.parse(document.getElementById('tags-data').textContent);
4) Move your Javascript code to an external .js file, and set up the Content-Security-Policy header to prohibit inline Javascript because it's a security risk. Note that since the json_script tag generates JSON, not Javascript, it's safe and is allowed regardless of your Content-Security-Policy setting.
4) 将您的 Javascript 代码移至外部 .js 文件,并设置 Content-Security-Policy 标头以禁止内联 Javascript,因为它存在安全风险。请注意,由于 json_script 标记生成 JSON,而不是 Javascript,因此无论您的 Content-Security-Policy 设置如何,它都是安全的并且允许使用。
Original Answer:
原答案:
WARNING: If any of the strings are user-controlled, this is insecure
警告:如果任何字符串是用户控制的,这是不安全的
JSON isJavascript source code. I.e. the JSON representation of an array is the Javascript source code you need to define the array.
JSON是Javascript 源代码。即数组的 JSON 表示是定义数组所需的 Javascript 源代码。
So after:
所以之后:
var tagbs = {{ tags|safe }};
tagbsis a JavaScript array containing the data you want. There's no need to call JSON.parse(), because the web browser already parsed it as JavaScript source code.
tagbs是一个包含所需数据的 JavaScript 数组。无需调用 JSON.parse(),因为 Web 浏览器已将其解析为 JavaScript 源代码。
So you should be able to do
所以你应该能够做到
var tagbs = {{ tags|safe }};
alert(tagbs[0].fields.ParentVideoFile);
and that should show "4".
那应该显示“4”。
WARNING: With this old method, strings containing "</script>" will not work, they will go horribly wrong. This is because the browser will treat </script> as the end of the script. If any of the strings are user-entered data, this is an exploitable security flaw - see comment 14 here for more details. Use the more modern method above, instead.
警告:使用这种旧方法,包含“</script>”的字符串将不起作用,它们会出错。这是因为浏览器会将 </script> 视为脚本的结尾。如果任何字符串是用户输入的数据,则这是一个可利用的安全漏洞 -有关更多详细信息,请参阅此处的注释 14。改用上面更现代的方法。
回答by Martijn Pieters
You want to JSON-ify the data in the template; JSON is already Javascript really (it's a subset:
您想对模板中的数据进行 JSON 化;JSON 已经是真正的 Javascript(它是一个子集:
{% if tags %}
var tgs = {{ tags }};
{% endif %}
Note that tagsis already JSON (thus JavaScript) data and can be inserted directly; no need to escape (there is no HTML here, it's JavaScript instead).
请注意,tags已经是JSON(JavaScript的因而)数据和可以插入直接; 无需转义(此处没有 HTML,而是 JavaScript)。
Or you could use this Django snippetand do it straight in the template (no need to call serializers.serializein the annotatemethod):
或者您可以使用此Django 代码段并直接在模板中执行(无需调用serializers.serialize该annotate方法):
var tgs = {{ tags|jsonify }};
回答by alix
You can also use simplejsonfrom django.utils. Like:
您也可以使用simplejson来自django.utils. 喜欢:
oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
dump = simplejson.dumps(oldAnnotations)
return HttpResponse(dump, mimetype='application/json')
You can parse and reach all data in this from JS side.
您可以从 JS 端解析和访问此中的所有数据。

