代码之家  ›  专栏  ›  技术社区  ›  chernevik

通过Django将Python数据传递给JavaScript

  •  51
  • chernevik  · 技术社区  · 15 年前

    我正在使用Django和Apache为网页提供服务。我的JavaScript代码目前包含一个数据对象,其值将根据用户从选项菜单中的选择显示在各种HTML小部件中。我想从Python字典中派生这些数据。我想我知道如何在HTML中嵌入JavaScript代码,但如何在脚本中嵌入数据对象(动态),以便脚本的函数可以使用它?

    换句话说,我想从Python字典创建一个JavaScript对象或数组,然后将该对象插入JavaScript代码,然后将JavaScript代码插入HTML。

    我认为这种结构(例如,JavaScript代码中变量中嵌入的数据)不太理想,但作为新手,我不知道其他选择。我看过Django序列化函数的编写,但在我能够首先将数据输入JavaScript代码之前,这些函数对我没有帮助。

    7 回复  |  直到 15 年前
        1
  •  81
  •   Chris Adams    6 年前

    n、 b.见底部的2018年更新

    我建议不要在Django模板中添加太多JavaScript,因为它往往很难编写和调试,尤其是在项目扩展时。相反,尝试将所有JavaScript编写在模板加载的单独脚本文件中,并在模板中仅包含一个JSON数据对象。这允许您通过以下方式运行整个JavaScript应用程序 JSLint ,缩小它,等等。您可以使用静态HTML文件测试它,而不依赖于您的Django应用程序。使用simplejson这样的库还可以节省编写冗长的序列化代码的时间。

    如果您没有假设您正在构建一个AJAX应用程序,那么可以这样做:

    他认为:

    from django.utils import simplejson
    
    
    def view(request, …):
        js_data = simplejson.dumps(my_dict)
        …
        render_template_to_response("my_template.html", {"my_data": js_data, …})
    

    在模板中:

    <script type="text/javascript">
        data_from_django = {{ my_data }};
        widget.init(data_from_django);
    </script>
    

    请注意,数据类型很重要:如果 my_data escape escapejs 过滤并确保JavaScript安全地处理数据以避免 cross-site scripting 攻击。

    time_t = time.mktime(my_date.timetuple())
    

    在JavaScript中,假设您做了如下操作 time_t = {{ time_t }} 根据以上代码片段的结果:

    my_date = new Date();
    my_date.setTime(time_t*1000);
    

    编辑:请注意,javascript中的setTime以毫秒为单位,而time.mktime的输出以秒为单位。这就是为什么我们需要乘以1000

    the HTML5 data API 达到 near universal browser support 而且传递简单(非列表/dict)值非常方便,特别是如果您可能希望基于这些值应用CSS规则,并且不关心不支持的Internet Explorer版本。

    <div id="my-widget" data-view-mode="tabular">…</div>
    
    let myWidget = document.getElementById("my-widget");
    console.log(myWidget.dataset.viewMode); // Prints tabular
    somethingElse.addEventListener('click', evt => {
        myWidget.dataset.viewMode = "list";
    });
    

    data- 属性我使用它来隐藏进度小部件,直到用户选择要处理的内容,或者根据获取结果有条件地显示/隐藏错误,或者甚至使用类似CSS的方式显示活动记录计数 #some-element::after { content: attr(data-active-transfers); }

        2
  •  44
  •   wilblack    12 年前

    <script type="text/javascript">
        data_from_django = {{ my_data|safe }};
        widget.init(data_from_django);
    </script>
    
        3
  •  6
  •   kenlukas Uday Allu    5 年前

    截至2018年年中,最简单的方法是使用Python的JSON模块,simplejson现在已不推荐使用。当心,@wilback提到你需要防止Django的自动转义 safe 过滤或 autoescape 贴上标签 off 选项在这两种情况下,都可以在视图中将词典的内容添加到上下文中

    import json
     def get_context_data(self, **kwargs):
        context['my_dictionary'] = json.dumps(self.object.mydict)
    

    然后在模板中添加@wilblack建议的内容:

    template.html

    <script>
        my_data = {{ my_dictionary|safe }};
    </script>
    
        4
  •  3
  •   Ned Batchelder    15 年前

    <script> 在.html模板中添加标记,然后构建数据结构。模板语言不仅适用于HTML,还可以处理Javascript对象文本。

    Paul是对的:最好使用json模块创建json字符串,然后将该字符串插入模板中。这将最好地处理引用问题,并轻松处理深层结构。

        5
  •  2
  •   Paul McMillan    15 年前

        6
  •  1
  •   Community miroxlav    7 年前

    请参阅对的相关回复 this question . 一个选择是使用 jsonpickle 在Python对象和JSON/Javascript对象之间序列化。它包装simplejson并处理simplejson通常不接受的事情。

        7
  •  1
  •   bluszcz    15 年前

    将Java脚本嵌入到Django模板中是非常困难的 相当地 总是坏主意。

    相当地 ,因为这条规则有一些例外。

    一切都取决于您的Java脚本代码站点和功能。

    最好有单独的静态文件,比如JS,但问题是每个单独的文件都需要另一个connect/GET/request/response机制。有时,对于小的一个,两行代码os JS将其放入模板中,然后使用django templatetags机制-您可以在其他模板中使用is;)