Django模板变量和Javascript

2020/10/12 22:21 · javascript ·  · 0评论

当我使用Django模板渲染器渲染页面时,可以传入包含各种值的字典变量,以使用来在页面中对其进行操作{{ myVar }}

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

{{variable}}直接替换为HTML。查看资料;它不是“变量”或类似的变量。它只是渲染的文本。

话虽如此,您可以将这种替换形式添加到JavaScript中。

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

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

小心检查票证#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>

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

<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团队可以解决这个限制。

请注意,如果要将变量传递给外部.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

我也一直在为此苦苦挣扎。从表面上看,上述解决方案似乎可行。但是,django架构要求每个html文件都有其自己的呈现变量(即{{contact}}呈现为contact.html,而呈现{{posts}}给egindex.html等)。另一方面,<script>标记出现{%endblock%}base.htmlfrom的后面contact.htmlindex.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照常进行。当然,这仅与获取内容有关。关于安全性,只需遵循其他答案即可。

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

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

Django的escapejs句柄正确处理了引号,JSON.parse()并将字符串转换回JS对象。

我在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>

从Django 2.1+开始,有一个很好的简单方法,使用内置模板标签json_script一个简单的例子是:

在模板中声明变量:

{{ variable|json_script:'name' }}

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

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

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

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

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>

这样,您将保留数据类型,在这种情况下,这是一种安排

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 }}

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

<button type="button" onclick="myJavascriptFunction('{{ my_django_variable }}')"></button>
<script>
    myJavascriptFunction(djangoVariable){
       alert(djangoVariable);
    }
</script>
本文地址:http://javascript.askforanswer.com/djangomobanbianlianghejavascript.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!