39

This question must be obvious but I can't figure it out.

In a template, I link to a js file in my media directory. From that file, I would like to access a context variable like {{my_chart}}.

But is the syntax different?? Thank you!!

shaedrich
  • 5,457
  • 3
  • 26
  • 42
user963936
  • 659
  • 1
  • 7
  • 15
  • Possible duplicate of [Django Template Variables and Javascript](http://stackoverflow.com/questions/298772/django-template-variables-and-javascript) – Cory Jan 17 '17 at 04:10

4 Answers4

35

In addition to Andrzej Bobak's answer, you can also generate a global variable in Javascript from your template. For example, your template might generate code like this:

<script>
   var my_chart = {{ the_chart }};
</script>

Your script could then refer to my_chart.

Brian Neal
  • 31,821
  • 7
  • 55
  • 59
  • @Brian_Neal how does this work? I.e., you can just do something like `console.log(my_chart);` in the javascript file, and you don't have to declare it anywhere? – YPCrumble Nov 10 '15 at 18:53
  • @YPCrumble It's declared in the html that is generated by Django. If that same html file also includes an external javascript file, that javascript can refer to that variable. – Brian Neal Nov 11 '15 at 20:11
  • 4
    This is brilliant answer, as long as you declare the global variable before you import your js file, you should be fine. Thanks. – almost a beginner Feb 28 '17 at 03:28
  • This is unsafe if {{ the_chart }} has any user entered values. What if a user decides to enter "<>/:'\;" ? – Ryan McGrath Jan 27 '22 at 04:12
  • 1
    @RyanMcGrath I haven't done Django in a long time but I believe there was/is a filter to escape javascript so maybe `{{ the_chart|escapejs }}`. – Brian Neal Jan 28 '22 at 19:31
26

I don't think it's possible this way. If you want to access some data provided by the view, you have to pass it to the js function.

Example

js file:

my_cool_js_function(some_param){
    // do some cool stuff
}

view

// some html code

my_cool_js_function({{param}})

hope this helps :)

Andrzej Bobak
  • 2,106
  • 3
  • 28
  • 36
  • 3
    Remember to take a look to [{{ value|escapejs }}](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs) – dani herrera Dec 30 '11 at 21:00
23

I would also add because I ran into the error a few times that if the python variable is an object it will throw a syntax error unless you put it in quotes, in other words, within your template,

<script>
   var my_var = '{{ python_object|escapejs }}';
</script>

Furthermore, before putting that object in the context it is best to first serialize it to JSON, or you'll end up having to do string parsing. I found also that date objects needed to be converted to strings before this step.

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)

And finally, in the JS you can then iterate through the object properly and use the values as you probably would have in python by doing:

var my_var_parsed = jQuery.parseJSON(my_var);
mastachimp
  • 438
  • 3
  • 14
14

There is now a more secure way to pass context to a javascript file using the built-in template tag json_script with an argument which would be the id set for the created element.

Use case would be:

{{ mydata|json_script:"mydata" }}

Then link your javascript file:

<script src="{% static 'myjavascriptfile.js' %}"></script>

the script tag would have to come after the template tag i'm guessing

Which can then be accessed in your javascript file like:

const mydata = JSON.parse(document.getElementById('mydata').textContent);

Sources

django 3.1 docs json_script

Another source with a proper explanation

name-andy
  • 423
  • 1
  • 5
  • 15