需要Django中上下文变量的Javascript最佳做法

时间:2018-10-08 15:49:27

标签: javascript django django-templates django-staticfiles

直到现在,我一直在使用{%load static%}将脚本包含在模板中,并将javascript代码放在与html文件分开的静态目录中,因为我认为这是最佳做法。

但是我越来越需要在javascript中使用上下文变量。由于模板标记无法直接集成到单个javascript静态文件中(据我所知),因此我一直在使用选择器从呈现的模板中将这些值导入javascript。例如:

<!--template.html-->
<div id="url_ajax" style="display:none">{% url 
"images:products" %}</div>
{%load static%}
<script src="{% static "js/ajax.js" %}"></script>

/*Ajax.js*/
url_ajax = document.getElementById("url_ajax").innerHTML
$.post(url_ajax, {
      rankit: this.rankit,
      pd: JSON.stringify(pd)
    },
    function(data) {
      if (data['status'] == 'ok') {
        [...]
      }
    }
  );

尽管这可行,但由于安全原因或可伸缩性,我觉得这不是一个好习惯。但是我不知道将上下文变量集成到javascript中而不是直接将javascript代码直接集成到模板中的另一种方法,如果该代码将在许多模板中使用,这也不是一个好方法。

作为Django学习者,我想知道在这种情况下最常用的方法:从呈现的模板中获取上下文变量的单独的javascript文件,直接插入模板html中的javascript代码或我使用的第三种方法不知道吗?

1 个答案:

答案 0 :(得分:1)

我真的不喜欢您的解决方案,不需要创建额外的html元素来传递django变量并从JS读取它。这容易出错,并且会将不需要的html元素添加到DOM中。

相反,我推荐两种解决方案:

解决方案1 ​​

在模板中使用JS脚本,您将在其中转储JS变量,然后直接从JS文件中使用它们。为此,我通常会在自定义JS代码之前的模板之前中有一个脚本,在其中定义一个包含所有Django变量的全局JS对象,如下所示:

    <script>
        var g_django = {
            url1: '{% url "the_first_url" %}',
            url2: '{% url "the_second_url" %}',
            image: '{% static "images/an_image" %}'
        }
    </script>
    <script src='{% static "js/ajax.js" %}'></script>

现在,我可以在g_django.url1脚本中使用g_django.imagejs/ajax.js等。如果您不需要在django和JS之间共享很多东西,可以使用此方法。

解决方案2

如果您还有更多需要在Django和js之间共享的内容,并且希望获得更好的控制,则可以创建JS-Django模板,即在模板文件夹内 创建普通的JS文件。然后,可以将该文件包含在<script>标记内(在此处查看我的答案以获取使用CSS的类似解决方案:Django Use Static files URL in Static Files),或者甚至可以通过{{1}用作常规Django视图}。因此,您将在TemplateView文件夹中创建一个名为django_data.js的文件,在其中编写与django变量混合的JS代码,例如,其内容可能是这样的

templates

此文件随后需要通过TemplateView包含在您的urls.py中,如下所示:

    var g_django = {
        url1: '{% url "the_first_url" %}',
        url2: '{% url "the_second_url" %}',
        image: '{% static "images/an_image" %}'
    }

现在,您可以访问django_data_js /来查看JS变量,并确保所有内容都能正确呈现,当然您可以将其(作为模板)包含在脚本中,如下所示:

class django.views.generic.base.TemplateView

urlpatterns = [
    path('django_data_js/', TemplateView.as_view(template='django_data.js', content_type='application/javascript'), name='django_data_js' ),
]

请注意,包含模板js(使用 <script src='{% url "django_data_js" %}'></script> <script src='{% static "js/ajax.js" %}'></script> )和包含普通静态文件(使用url)之间的区别。这样您就可以在static内部使用g_django