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?

1

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.