Answers:
将{{variable}}
直接替换为HTML。查看资料;它不是“变量”或类似的变量。它只是渲染的文本。
话虽如此,您可以将这种替换形式添加到JavaScript中。
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
这为您提供了“动态” javascript。
escapejs
过滤器存在:escapejs('<>') -> u'\\u003C\\u003E'
注意检查票证#17419,以获取有关将类似的标签添加到Django核心中的讨论以及通过将此模板标签与用户生成的数据一起使用而引入的可能的XSS漏洞。amacneil的评论讨论了故障单中提出的大多数问题。
我认为最灵活,方便的方法是为要在JS代码中使用的变量定义模板过滤器。这样可以确保您的数据已正确转义,并且可以将其用于复杂的数据结构,例如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>
safe
仅将值标记为安全,而没有适当的转换和转义。
function myWidget(config) { /* implementation */ }
在JS文件中声明,然后在上使用myWidget({{ pythonConfig | js }})
。但是您不能在JS文件中使用它(如您所注意到的),因此它有其局限性。
对我有用的解决方案是使用模板中的隐藏输入字段
<input type="hidden" id="myVar" name="variable" value="{{ variable }}">
然后以这种方式在javascript中获取值,
var myVar = document.getElementById("myVar").value;
从Django 2.1开始,专门针对此用例引入了一个新的内置模板标记:json_script
。
https://docs.djangoproject.com/zh-CN/3.0/ref/templates/builtins/#json-script
新标签将安全地序列化模板值并防止XSS。
Django文档摘录:
安全地将Python对象作为JSON输出,包装在标记中,可以与JavaScript一起使用。
这是我很容易做的事情:我为模板修改了base.html文件,并将其放在底部:
{% if DJdata %}
<script type="text/javascript">
(function () {window.DJdata = {{DJdata|safe}};})();
</script>
{% endif %}
然后,当我想在javascript文件中使用变量时,我创建了一个DJdata字典,并通过json将其添加到上下文中: context['DJdata'] = json.dumps(DJdata)
希望能帮助到你!
对于字典,最好先编码为JSON。您可以使用simplejson.dumps(),或者如果要从App Engine中的数据模型进行转换,则可以使用GQLEncoder库中的encode()。
我面临着类似的问题,S.Lott建议的答案为我工作。
<script type="text/javascript">
var a = "{{someDjangoVariable}}"
</script>
但是,我想在这里指出主要的实现限制。如果您打算将javascript代码放在其他文件中,然后将该文件包含在模板中。这行不通。
仅当主模板和javascript代码位于同一文件中时,此方法才有效。也许django小组可以解决这个限制。
我也一直在为此苦苦挣扎。从表面上看,上述解决方案应该可行。但是,django架构要求每个html文件都有其自己的呈现变量(即{{contact}}
呈现为contact.html
,而呈现{{posts}}
给eg index.html
等)。另一方面,<script>
标记出现{%endblock%}
在base.html
from的后面contact.html
并index.html
继承。这基本上意味着任何解决方案,包括
<script type="text/javascript">
var myVar = "{{ myVar }}"
</script>
必然会失败,因为变量和脚本不能共存于同一文件中。
我最终想出并为我工作的一个简单解决方案是,简单地用带有id的标签包装变量,然后在js文件中引用它,如下所示:
// index.html
<div id="myvar">{{ myVar }}</div>
然后:
// somecode.js
var someVar = document.getElementById("myvar").innerHTML;
并且只包含<script src="static/js/somecode.js"></script>
在base.html
照常进行。当然,这只是关于获取内容。关于安全性,只需遵循其他答案即可。
.textContent
而不是.innerHTML
,因为否则,经过HTML编码的实体也将成为JS变量的一部分。但是即使那样也可能无法以1:1的比例复制(我不确定)。
请注意,如果要将变量传递给外部.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
您可以在字符串中声明数组变量的地方组装整个脚本,如下所示,
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})
在模板中,您会收到它,并以书面形式将其解释为htm代码,例如您需要的javascript代码之前
模板
{{ prueba|safe }}
在代码的其余部分下面,请记住,在示例中使用的变量是data2
<script>
console.log(data2);
</script>
这样,您将保留数据类型,在这种情况下,这是一种安排
aaa
仅包含数字时才使用此选项,否则可以使用XSS(脚本注入)。