如何在 JavasScript 中使用“views.py”中的变量,在 Django 模板中使用“<script></script>”中的变量?
- 2024-12-06 08:40:00
- admin 原创
- 147
问题描述:
当我使用 Django 模板渲染器渲染页面时,我可以传入包含各种值的字典变量,以便使用在页面中操作它们{{ myVar }}
。
有没有办法在 JavaScript 中访问相同的变量<script></script>
(也许使用DOM;我不知道 Django 如何使变量可访问)?我希望能够使用基于传入变量中包含的值的Ajax查找来查找详细信息。
解决方案 1:
直接替换到 HTML 中。查看源代码{{variable}}
;它不是“变量”或类似的东西。它只是呈现的文本。
话虽如此,您可以将这种替换放入您的 JavaScript 中。
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
这为您提供了“动态” JavaScript 代码。
解决方案 2:
注意:请查看票号#17419,了解有关在 Django 核心中添加类似标签的讨论,以及使用此模板标签与用户生成的数据可能引入的 XSS 漏洞。来自 amacneil 的评论讨论了票中提出的大部分问题。
我认为最灵活、最方便的方法是为要在 JavaScript 代码中使用的变量定义一个模板过滤器。这样可以确保数据得到正确转义,并且可以将其用于复杂的数据结构,例如dict
和list
。
以下是模板过滤器的示例:
// myapp/templatetags/js.py
from django.utils.safestring import mark_safe
from django.template import Library
import json
register = Library()
@register.filter(is_safe=True)
def js(obj):
return mark_safe(json.dumps(obj))
此模板过滤器将变量转换为 JSON 字符串。您可以像这样使用它:
// myapp/templates/example.html
{% load js %}
<script type="text/javascript">
var someVar = {{ some_var | js }};
</script>
解决方案 3:
对我有用的解决方案是使用模板中的隐藏输入字段
<input type="hidden" id="myVar" name="variable" value="{{ variable }}">
然后通过 JavaScript 获取值,
var myVar = document.getElementById("myVar").value;
解决方案 4:
从 Django 2.1 开始,专门针对这种用例引入了一个新的内置模板标签:json_script()。
新的标签将安全地序列化模板值并防止XSS。
Django 文档摘录:
安全地将 Python 对象输出为 JSON,并包裹在标签中,以供 JavaScript 使用。
解决方案 5:
新文档说用于{{ mydata|json_script:"mydata" }}
防止代码注入。
这里给出了一个很好的例子:
{{ mydata|json_script:"mydata" }}
<script>
const mydata = JSON.parse(document.getElementById('mydata').textContent);
</script>
解决方案 6:
从 Django 2.1+ 开始,有一个简单的方法,使用内置模板标签json_script实现。一个简单的例子是:
在模板中声明变量:
{{ variable|json_script:'name' }}
然后在<script>
JavaScript 代码中调用该变量:
var js_variable = JSON.parse(document.getElementById('name').textContent);
对于像“User”这样更复杂的变量,使用 Django 内置的序列化程序可能会出现“User 类型的对象不是 JSON 可序列化”这样的错误。在这种情况下,您可以使用 Django Rest Framework 来处理更复杂的变量。
解决方案 7:
对于以文本形式存储在 Django 字段中的 JavaScript 对象(需要再次成为动态插入到页面脚本中的 JavaScript 对象),您需要同时使用escapejs
和JSON.parse()
:
var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}");
Djangoescapejs
正确处理引用,并将JSON.parse()
字符串转换回 JS 对象。
解决方案 8:
这是我非常轻松地做的事情:我修改了模板的base.html文件并将其放在底部:
{% if DJdata %}
<script type="text/javascript">
(function () {window.DJdata = {{DJdata|safe}};})();
</script>
{% endif %}
然后,当我想在 JavaScript 文件中使用变量时,我会创建一个 DJdata 字典并通过 JSON 内容将其添加到上下文中:context['DJdata'] = json.dumps(DJdata)
解决方案 9:
对于字典,最好先将其编码为 JSON。您可以使用 simplejson.dumps(),或者如果您想从App Engine中的数据模型进行转换,则可以使用 GQLEncoder 库中的 encode()。
解决方案 10:
请注意,如果您想将变量传递给外部.js 脚本,那么您需要在脚本标签前面加上另一个声明全局变量的脚本标签。
<script type="text/javascript">
var myVar = "{{ myVar }}"
</script>
<script type="text/javascript" src="{% static "scripts/my_script.js" %}"></script>
data
在视图中像往常一样定义get_context_data
def get_context_data(self, *args, **kwargs):
context['myVar'] = True
return context
解决方案 11:
我遇到了类似的问题,S.Lott 建议的答案对我有用。
<script type="text/javascript">
var a = "{{someDjangoVariable}}"
</script>
但是,我想指出一个主要的实施限制。如果您打算将 javascript 代码放在不同的文件中,并将该文件包含在模板中。这将行不通。
仅当您的主模板和 JavaScript 代码位于同一文件中时,此方法才有效。Django 团队可能可以解决此限制。
解决方案 12:
我也一直在为此苦苦挣扎。表面上看,上述解决方案应该有效。但是,Django 架构要求每个 HTML 文件都有自己的渲染变量(即,{{contact}}
渲染到contact.html
,而{{posts}}
转到 ,例如,index.html
等等)。另一方面,标签出现在in from which和inherit<script>
之后。这基本上意味着任何包括的解决方案{%endblock%}
`base.htmlcontact.html
index.html`
<script type="text/javascript">
var myVar = "{{ myVar }}"
</script>
注定会失败,因为变量和脚本不能共存于同一个文件中。
我最终想出了一个对我来说可行的简单解决方案,那就是简单地用带有 id 的标签包装变量,然后在 JavaScript 文件中引用它,如下所示:
// index.html
<div id="myvar">{{ myVar }}</div>
进而:
// somecode.js
var someVar = document.getElementById("myvar").innerHTML;
并像往常一样包含<script src="static/js/somecode.js"></script>
进去base.html
。当然,这只是为了获取内容。关于安全性,请按照其他答案操作。
解决方案 13:
我发现我们可以像这样将 Django 变量传递给 JavaScript 函数:
<button type="button" onclick="myJavascriptFunction('{{ my_django_variable }}')"></button>
<script>
myJavascriptFunction(djangoVariable){
alert(djangoVariable);
}
</script>
解决方案 14:
我在 Django 2.1 中使用了这种方法,对我来说很有效。而且这种方法很安全(参考):
Django 端:
def age(request):
mydata = {'age':12}
return render(request, 'test.html', context={"mydata_json": json.dumps(mydata)})
HTML 端:
<script type='text/javascript'>
const mydata = {{ mydata_json|safe }};
console.log(mydata)
</script>
解决方案 15:
您可以在 Django 模板中使用views.py
JavaScript 中的变量。<script></script>
例如,如果您将包含字典persons
列表的字典传递views.py
给 Django 模板,如下所示:
# "views.py"
from django.shortcuts import render
def test(request, id=None, slug=None):
persons = [
{'name':'John', 'age':36},
{'name':'David','age':24}
]
return render(request, 'index.html', {"persons":persons})
然后,您可以在 Django 模板中使用 JavaScript 中的变量,<script></script>
如下所示:
# "index.html"
<script>
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
</script>
然后,这些结果显示在控制台上:
John 36
David 24
请注意,如果使用 JavaScript 的变量和for
循环,控制台上将显示意外结果:
# "index.html"
<script>
let js_persons = "{{ persons }}"
for (let i = 0; i < js_persons.length; i++) {
console.log(js_persons[i]);
}
</script>
当然,你可以comment
在 JavaScript 中使用标签,<script></script>
在 Django 模板中如下所示:
# "index.html"
<script>
{% for person in persons %}
{% comment %}
console.log("{{ person.name }} {{ person.age}}");
{% endcomment %}
{% endfor %}
</script>
# "index.html"
<script>
{% comment %}
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
{% endcomment %}
</script>
# "index.html"
{% comment %}
<script>
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
</script>
{% endcomment %}
解决方案 16:
JavaScript 中有两件事对我有用:
'{{context_variable|escapejs }}'
其他:
在views.py中:
from json import dumps as jdumps
def func(request):
context={'message': jdumps('hello there')}
return render(request,'index.html',context)
HTML 内容如下:
{{ message|safe }}
解决方案 17:
您可以将整个脚本组合起来,其中数组变量在字符串中声明,如下所示,
文件views.py
aaa = [41, 56, 25, 48, 72, 34, 12]
prueba = "<script>var data2 =["
for a in aaa:
aa = str(a)
prueba = prueba + "'" + aa + "',"
prueba = prueba + "];</script>"
这将生成如下字符串
prueba = "<script>var data2 =['41','56','25','48','72','34','12'];</script>"
有了这个字符串之后,你必须将它发送给模板。
文件views.py
return render(request, 'example.html', {"prueba": prueba})
在模板中,你接收它并以文学的方式将其解释为 HTML 代码,就在你需要它的 JavaScript 代码之前,例如
模板
{{ prueba|safe }}
下面是代码的其余部分。请记住,示例中使用的变量是data2。
<script>
console.log(data2);
</script>
这样,您将保留数据类型,在本例中是一种安排。
解决方案 18:
有各种各样的答案指向这一点json_script
。与人们的想法相反,这并不是一个万能的解决方案。
例如,当我们想要将 for 循环内生成的动态变量传递给 JavaScript 时,最好使用data-attributes之类的东西。
请在此处查看更多详细信息。
解决方案 19:
如果你想将变量作为参数直接传递给函数,那么试试这个
<input type="text" onkeyup="somefunction('{{ YOUR_VARIABLE }}')">
根据以前的答案,安全性可以得到提高。