【问题标题】:Getting a list from Django into Javascript as an array将列表从 Django 获取到 Javascript 作为数组
【发布时间】:2019-03-30 15:51:58
【问题描述】:

我有一个由 Django 中的 views.py 生成的 python 列表,我想将它传递给我的 HTML 模板中的 javascript。 我似乎无法将它作为数组放入 javscript...我需要评估列表/数组是否包含某些数字,但它是以字符串的形式出现的。

我将列表传递给我的 HTML 模板,如下所示:

def get_context_data(self, **kwargs):
    context = super(dashboardView, self).get_context_data(**kwargs)
    mylist = [10,22,33,45]
    context['mylist'] = mylist
    return context

当我使用时:

<h1 id = "list"> {{mylist}}</h1>

它在浏览器上显示为 它显示为 [10,22,33,45]

然后在我的模板中我使用的是javascript:

var mylist = document.getElementById("list").innerHTML;
for(i = 0; i < mylist.length; i++){
    console.log(mylist[i])
};

这会在控制台中返回:

'
[
1
0
,

2
2
........

我想要:

10
22
33
45

我尝试在 python 中转换为 JSON,并在 javascript 中对其进行解析,但似乎无法将此字符串转换为数组,或者不断出错。 对这里的最佳方法有什么想法吗?

【问题讨论】:

  • 在控制台打印mylist = document.getElementById("list").innerHTML;的值并发布

标签: javascript python django


【解决方案1】:

如果您绝对确定您的列表是安全的(我的意思是它永远不会包含用户输入的任何内容),那么这非常简单。

在你看来:

context={"my_list": ["item1", "item2"]}

在您的模板中:

{{ my_list|safe }}

呈现为:

['item1', 'item2']

例如:

{{ my_list|safe }}.forEach(item => {
  console.log(item)
})

令人印象深刻的是,如果你传递带有撇号的字符串,Django 会自动更改引号类型,所以

context = {"my_list": ["item1", "it'em2"]}

呈现为(注意双引号):

['item1', "it'em2"]

所以

{{ my_list|safe }}.forEach

仍然有效(在 Django 3.2.6 上测试)。

即使这样也有效:

context = {"my_list": ["item1", "it'em\"2"]}

呈现为:

['item1', 'it\'em"2']

所以

{{ my_list|safe }}.forEach

仍然有效。

但是,正如我在顶部所说,如果您的列表可能包含来自用户的输入,我仍然不会相信这种方法。

【讨论】:

  • 嗨@Chris,您能否详细说明在使用用户输入时哪些情况会导致这是一个坏主意?例如,如果用户传入SomeModel.objects.all().delete(),理论上会删除表,但这会首先被 JSON.parse 捕获,不是吗?
  • 嗨,马特,不,我不是,我自己什么都想不出来。我提出警告是因为我这里的解析不会考虑到安全性,而 |safe 禁用的转义会。问题不在于 Python 代码注入,问题在于 JavaScript 注入,如果被黑客入侵,可能会将来自恶意站点的内容加载到您的网页中,例如,在您的用户浏览器中窃取密码、挖掘比特币或其他内容。
【解决方案2】:

在视图中,您可以将对象设为 JSON 对象:

import json

mylistraw = [10,22,33,45]
mylist = json.dumps(mylistraw)
context = {''mylistjson': mylist}

现在你可以在 JavaScript 中使用你的对象了:

var mylist = JSON.parse("{{mylistjson}}")

【讨论】:

    【解决方案3】:

    Django 具有json_script 模板标签,通过转义&lt;&gt;&amp; 字符来解决XSS 漏洞。

    Django json_script docs here

    【讨论】:

      【解决方案4】:

      在您的情况下,一种简单的方法是将列表作为字符串','.join(mylist) 发送。然后在您的模板中,您可以简单地在js 中使用split(',')

      观看次数

      mylist = [10,22,33,45]
      context['mylist'] = ','.join([str(i) for i in mylist])
      

      html & js

      var mylist = document.getElementById("list").innerHTML;
      mylist = mylist.split(',')
      for(i = 0; i < mylist.length; i++){
          console.log(mylist[i])
      };
      

      或者如果你的 js 也在模板中

      var mylist = '{{mylist}}'.split(',');
      for(i = 0; i < mylist.length; i++){
          console.log(mylist[i])
      };
      

      【讨论】:

      • 感谢您的回复 - 这已经接近工作了,但是当我遍历对象时,第一个和最后一个项目将方括号作为其值的一部分。 eg: [10 是第一个可迭代对象的值。
      【解决方案5】:

      您可以简单地使用tojson标签将python列表转换为js数组。

      它会像 -

      var mylist = {{mylist|tojson}};
      for(i = 0; i < mylist.length; i++){
          console.log(mylist[i])
      };
      

      尝试一下,如果出现任何问题,请告诉我。

      【讨论】:

      【解决方案6】:

      在 JavaScript 而不是 HTML 中设置列​​表值。

      <script>
      var mylist = {{mylist}};
      for(i = 0; i < mylist.length; i++){
          console.log(mylist[i])
      };
      <\ script>
      

      您需要在 HTML 模板文件中执行此操作,而不是在外部 JS 文件中。

      【讨论】:

        猜你喜欢
        • 2013-04-07
        • 1970-01-01
        • 2015-02-25
        • 2021-07-18
        • 2015-05-09
        • 1970-01-01
        • 2019-06-29
        • 1970-01-01
        • 2017-02-04
        相关资源
        最近更新 更多