268

当我使用 Django 模板渲染器渲染页面时,我可以传入一个包含各种值的字典变量,以便在页面中使用{{ myVar }}.

有没有办法在 Javascript 中访问相同的变量(也许使用 DOM,我不知道 Django 如何使变量可访问)?我希望能够根据传入的变量中包含的值使用 AJAX 查找来查找详细信息。

4

16 回答 16

365

{{variable}}直接替换到 HTML 中。做一个视图源;它不是“变量”或类似的东西。它只是呈现的文本。

话虽如此,您可以将这种替换放入您的 JavaScript 中。

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}";
</script>

这为您提供了“动态”javascript。

于 2008-11-18T14:00:58.737 回答
81

小心检查票#17419以讨论在 Django 核心中添加类似标签以及使用此模板标签和用户生成的数据可能引入的 XSS 漏洞。amacneil 的评论讨论了票中提出的大部分问题。


我认为最灵活、最方便的方法是为要在 JS 代码中使用的变量定义模板过滤器。这使您可以确保您的数据被正确转义,并且您可以将其用于复杂的数据结构,例如dictlist。这就是为什么我写这个答案,尽管有很多赞成的答案。

这是模板过滤器的示例:

// 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>
于 2014-08-28T00:14:04.210 回答
63

对我有用的解决方案是使用模板中的隐藏输入字段

<input type="hidden" id="myVar" name="variable" value="{{ variable }}">

然后以这种方式在javascript中获取值,

var myVar = document.getElementById("myVar").value;
于 2011-12-13T01:15:07.260 回答
48

从 Django 2.1 开始,专门为此用例引入了一个新的内置模板标签:json_script.

https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script

新标签将安全地序列化模板值并防止 XSS。

Django 文档摘录:

将 Python 对象安全地输出为 JSON,包装在标签中,可与 JavaScript 一起使用。

于 2019-01-19T19:53:55.890 回答
10

这是我正在做的非常容易的事情:我为我的模板修改了我的 base.html 文件并将其放在底部:

{% if DJdata %}
    <script type="text/javascript">
        (function () {window.DJdata = {{DJdata|safe}};})();
    </script>
{% endif %}

然后,当我想在 javascript 文件中使用变量时,我创建了一个 DJdata 字典,并通过 json 将其添加到上下文中:context['DJdata'] = json.dumps(DJdata)

希望能帮助到你!

于 2015-03-13T12:31:04.067 回答
10

对于以文本形式存储在 Django 字段中的 JavaScript 对象,它需要再次成为动态插入到页面脚本中的 JavaScript 对象,您需要同时使用escapejsJSON.parse()

var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}");

Djangoescapejs正确处理引用,JSON.parse()并将字符串转换回 JS 对象。

于 2017-03-07T19:25:23.320 回答
9

使用内置模板标签json_script从 Django 2.1+ 实现了一种非常简单的方法。一个简单的例子是:

在模板中声明变量:

{{ variable|json_script:'name' }}

<script>然后在您的Javascript中调用该变量:

var js_variable = JSON.parse(document.getElementById('name').textContent);

对于更复杂的变量,如“用户”,使用 Django 的内置序列化程序,您可能会收到“用户类型的对象不是 JSON 可序列化”之类的错误。在这种情况下,您可以使用 Django Rest Framework 来允许更复杂的变量。

于 2020-07-20T07:33:58.213 回答
8

对于字典,最好先编码为 JSON。您可以使用 simplejson.dumps(),或者如果您想从 App Engine 中的数据模型进行转换,您可以使用 GQLEncoder 库中的 encode()。

于 2008-11-20T08:19:31.700 回答
7

文档说用于{{ mydata|json_script:"mydata" }}防止代码注入。

这里给出了一个很好的例子:

{{ mydata|json_script:"mydata" }}
<script>
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
</script>
于 2020-12-14T09:19:53.337 回答
5

我面临着类似的问题,S.Lott 建议的答案为我工作。

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}"
</script>

但是,我想在这里指出主要的实现限制。如果您打算将您的 javascript 代码放在不同的文件中,并将该文件包含在您的模板中。这行不通。

这仅在您的主模板和 javascript 代码位于同一文件中时才有效。可能 django 团队可以解决这个限制。

于 2015-10-07T17:03:39.777 回答
5

请注意,如果要将变量传递给外部 .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
于 2018-10-16T03:57:34.590 回答
4

我也一直在为此苦苦挣扎。从表面上看,上述解决方案似乎应该有效。但是,django 架构要求每个 html 文件都有自己的渲染变量(即{{contact}}渲染到contact.html,而{{posts}}转到 egindex.html等)。另一方面,<script>标签出现在{%endblock%}in base.htmlfrom whichcontact.htmlindex.htmlinherit 之后。这基本上意味着任何解决方案,包括

<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当然,这只是关于获取内容。关于安全性,只需遵循其他答案即可。

于 2018-11-09T23:08:31.817 回答
4

我在 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>
于 2020-04-16T17:51:05.423 回答
3

我发现我们可以将 Django 变量传递给 javascript 函数,如下所示:-

<button type="button" onclick="myJavascriptFunction('{{ my_django_variable }}')"></button>
<script>
    myJavascriptFunction(djangoVariable){
       alert(djangoVariable);
    }
</script>
于 2020-07-17T12:25:33.623 回答
0

您可以组装整个脚本,其中您的数组变量在字符串中声明,如下所示,

视图.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>"

获得此字符串后,您必须将其发送到模板

视图.py

return render(request, 'example.html', {"prueba": prueba})

在模板中,您收到它并以文学方式将其解释为 htm 代码,就在您需要它的 javascript 代码之前,例如

模板

{{ prueba|safe  }}

下面是代码的其余部分,请记住,示例中使用的变量是 data2

<script>
 console.log(data2);
</script>

这样你就可以保留数据的类型,在这种情况下是一种安排

于 2019-08-12T18:58:39.780 回答
0

在 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 }}
于 2020-03-29T17:21:57.260 回答