繁体   English   中英

将JSON数组从Django视图返回到模板

[英]Returning JSON array from a Django view to a template

我正在使用Django为项目创建一个基于Web的应用程序,我遇到了将数组从Django视图返回到模板的问题。

该数组将由JavaScript(JQuery)脚本用于在页面中显示的图像上绘制框。 因此,该数组将具有要绘制的框的坐标等。

这是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, ...})

作为一种调试方式,在模板的HTML部分中使用{{ tags }}将其作为输出(对于长行而言):

[{"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}}]

我假设它是JSON数组的正确格式。

稍后在模板中,我尝试在模板的JavaScript部分中实际使用tags变量,如下所示:

{% if tags %}
  var tagbs = {{ tags|safe }};
  var tgs = JSON.parse(tagbs);
  alert("done");
{% endif %}

如果我删除var tgs = JSON.parse(tagbs); 行,然后警报框弹出正常,其余的JavaScript按预期工作。 但是,让这一行破坏了剧本。

我希望能够遍历Django模型中的所有对象并获取JavaScript中的字段值。

我不确定我在这里做错了什么,有人能指出正确的方法吗?

使用Django 2.1+和现代网站的更新进行编辑:

现代的方法是:

1)将原始数据传递给模板,而不是JSON序列化数据。 即:

def annotate(request, ...):
    ...
    oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
    ...
    return render_to_response('vannotate.html', {'tags': oldAnnotations, ...})

2)在模板中,使用新的“json_script”过滤器来包含JSON数据:

{{ tags|json_script:"tags-data" }}

这将导致HTML看起来像这样:

<script id="tags-data" type="application/json">{"foo": "bar"}</script>

此标记对包含“</ script>”的字符串进行特殊处理,以确保它们正常工作。

3)在您的Javascript代码中,获取标签数据,如下所示:

var tags = JSON.parse(document.getElementById('tags-data').textContent);

4)将您的Javascript代码移动到外部.js文件,并设置Content-Security-Policy标头以禁止内联Javascript,因为它存在安全风险。 请注意,由于json_script标记生成JSON而不是Javascript,因此无论您的Content-Security-Policy设置如何,它都是安全的并且是允许的。

原答案:

警告:如果任何字符串是用户控制的,则这是不安全的

JSON Javascript源代码。 即数组的JSON表示是您定义数组所需的Javascript源代码。

之后:

var tagbs = {{ tags|safe }};

tagbs是一个包含所需数据的JavaScript数组。 没有必要调用JSON.parse(),因为Web浏览器已将其解析为JavaScript源代码。

所以你应该能做到

var tagbs = {{ tags|safe }};
alert(tagbs[0].fields.ParentVideoFile);

这应该显示“4”。

警告:使用这种旧方法,包含“</ script>”的字符串将不起作用,它们将出现严重错误。 这是因为浏览器会将</ script>视为脚本的结尾。 如果任何字符串是用户输入的数据,这是一个可利用的安全漏洞 - 有关更多详细信息,请参阅此处的注释14 请使用上面更现代的方法。

你想要JSON-ify 模板中的数据; JSON真的已经是Javascript(它是一个子集:

{% if tags %}
  var tgs = {{ tags }};
{% endif %}

注意, tags是已经JSON(JavaScript的因而)数据和可以直接插入; 无需逃避(这里没有HTML,而是JavaScript)。

或者您可以使用此Django片段并在模板中直接执行(无需在annotate方法中调用serializers.serialize ):

var tgs = {{ tags|jsonify }};

您也可以使用django.utils simplejson 喜欢:

oldAnnotations = lastFrame.videoannotation_set.filter(ParentVideoLabel=label)
dump = simplejson.dumps(oldAnnotations)

return HttpResponse(dump, mimetype='application/json')

您可以从JS端解析并覆盖此中的所有数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM