Django Template Variables and Javascript
When I render a page using the Django template renderer, I can pass in a dictionary variable containing various values to manipulate them in the page using {{ myVar }}
.
Is there a way to access the same variable in Javascript (perhaps using the DOM, I don't know how Django makes the variables accessible)? I want to be able to lookup details using an AJAX lookup based on the values contained in the variables passed in.
Solution 1:
The {{variable}}
is substituted directly into the HTML. Do a view source; it isn't a "variable" or anything like it. It's just rendered text.
Having said that, you can put this kind of substitution into your JavaScript.
<script type="text/javascript">
var a = "{{someDjangoVariable}}";
</script>
This gives you "dynamic" javascript.
Solution 2:
CAUTION Check ticket #17419 for discussion on adding similar tag into Django core and possible XSS vulnerabilities introduced by using this template tag with user generated data. Comment from amacneil discusses most of the concerns raised in the ticket.
I think the most flexible and handy way of doing this is to define a template filter for variables you want to use in JS code. This allows you to ensure, that your data is properly escaped and you can use it with complex data structures, such as dict
and list
. That's why I write this answer despite there is an accepted answer with a lot of upvotes.
Here is an example of template filter:
// myapp/templatetags/js.py
from django.utils.safestring import mark_safe
from django.template import Library
import json
register = Library()
@register.filter(is_safe=True)
def js(obj):
return mark_safe(json.dumps(obj))
This template filters converts variable to JSON string. You can use it like so:
// myapp/templates/example.html
{% load js %}
<script type="text/javascript">
var someVar = {{ some_var | js }};
</script>
Solution 3:
A solution that worked for me is using the hidden input field in the template
<input type="hidden" id="myVar" name="variable" value="{{ variable }}">
Then getting the value in javascript this way,
var myVar = document.getElementById("myVar").value;
Solution 4:
As of Django 2.1, a new built in template tag has been introduced specifically for this use case: json_script
.
https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
The new tag will safely serialize template values and protects against XSS.
Django docs excerpt:
Safely outputs a Python object as JSON, wrapped in a tag, ready for use with JavaScript.
Solution 5:
Here is what I'm doing very easily: I modified my base.html file for my template and put that at the bottom:
{% if DJdata %}
<script type="text/javascript">
(function () {window.DJdata = {{DJdata|safe}};})();
</script>
{% endif %}
then when I want to use a variable in the javascript files, I create a DJdata dictionary and I add it to the context by a json : context['DJdata'] = json.dumps(DJdata)
Hope it helps!