1

Until now I have been including scripts in my templates by using {% load static %} and having the javascript code in the static directory, separated from html files, because I thought it was the best practice.

But more and more I need to use context variables in the javascript. Since template tags cannot be integrated directly in the individual javascript static files (as far as I know), I have been importing these values in the javascript from the rendered template by using selectors. For example:

<!--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') {
        [...]
      }
    }
  );

Although this works, I am feeling this is not a good practice due to security reasons or scalability. But I do not know another way of integrating context variables in the javascript rather than integrating javascript code directly in the template, which is neither a good approach if that code will be used in many templates.

As a Django learner I would like to know which is the most often used approach in these situations: separated javascript files which takes context variables from the rendered template, javascript code inserted directly in the template html, or a third approach which I don´t know?

  • You should find some info here: https://stackoverflow.com/questions/298772/django-template-variables-and-javascript –  Oct 08 '18 at 15:57

1 Answers1

1

I don't really like your solution, there's no need to create an extra html element to pass the django variable and read it from JS. This is error prone and adds non-needed html elements to your DOM.

Instead I recommend two solutions:

Solution 1

Use a JS script in your template where you'll dump your JS variables and then use them directly from your JS files. To do that, I'll usually have a script inside my template before my custom JS code where I define a global JS object containing all Django variables, like this:

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

Now I can use g_django.url1, g_django.image etc from inside the js/ajax.js script. This can be used if you don't have many things you need to share between django and JS.

Solution 2

If you have more things you need to share between Django and js and you want to have better control you can create a JS-Django template i.e create a normal JS file inside your templates folder. This file can then either be included inside a <script> tag (check my answer here for a similar solution with css: Django Use Static files URL in Static Files) or, even better be used as a normal django view through a TemplateView. Thus, you'll create a file named django_data.js in your templates folder in which you'll write JS code mixed with django variables for example it's contents may be something like this

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

This file will then need to be included to your urls.py through a TemplateView something like this:

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' ),
]

Now you can visit django_data_js/ to take a look at your JS variables and be sure that everything renders correctly and of course you can include it (as a template) to your scripts like this:

    <script src='{% url "django_data_js" %}'></script>
    <script src='{% static "js/ajax.js" %}'></script>

Notice the difference between including the template-js (using url) and including the normal static file (using static). You'll then be able to use g_django from inside your js/ajax.js.

Serafeim
  • 14,962
  • 14
  • 91
  • 133