如何在 JavasScript 中使用“views.py”中的变量,在 Django 模板中使用“<script></script>”中的变量?

2024-12-06 08:40:00
admin
原创
147
摘要:问题描述:当我使用 Django 模板渲染器渲染页面时,我可以传入包含各种值的字典变量,以便使用在页面中操作它们{{ myVar }}。有没有办法在 JavaScript 中访问相同的变量<script></script>(也许使用DOM;我不知道 Django 如何使变量可访问)?我...

问题描述:

当我使用 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 代码中使用的变量定义一个模板过滤器。这样可以确保数据得到正确转义,并且可以将其用于复杂的数据结构,例如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>

解决方案 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 对象),您需要同时使用escapejsJSON.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.htmlindex.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.pyJavaScript 中的变量。<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 }}')">

根据以前的答案,安全性可以得到提高。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用