Django Template Variables and Javascript
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!
Related videos on Youtube
Arya V Nair
Updated on December 15, 2020Comments
-
Arya V Nair over 3 years
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.
-
Casebash almost 14 yearsNote though that according to this solution, this is vulnerable to injection attacks
-
Tomasz Zieliński over 12 years@Casebash: For such occasions
escapejs
filter exists:escapejs('<>') -> u'\\u003C\\u003E'
-
Mark over 12 yearsJust to add on to this for reference: if the "someDjangoVariable" so happens to be JSON, be sure to use {{ someDjangoVariable|safe }} to remove the "
-
AndyL about 12 yearsbe wary though. depending on how you use the variable/form, the user could put in whatever they want.
-
nu everest over 11 yearsyou may also want to set your input field to readonly (see this link w3schools.com/tags/att_input_readonly.asp)
-
Mikhail about 11 yearsAdditionally make sure that the string isn't broken into multiple lines.
-
Mario over 9 yearsDoes anyone know of a "gon" (github.com/gazay/gon) equivalent for Django?
-
Alan Evangelista over 9 yearsThis answer only works for a simple variable, it does not work for a complex data structure. In this case, the simplest solution is to add client-side code to traverse the data structure and build a similar one in Javascript. If the complex data structure is in JSON format, another solution is to serialize it, pass a serialized JSON to the Django template in server-side code and deserialize the JSON in a javascript object in client-side code. One answer below mentions this alternative.
-
Alan Evangelista over 9 yearsThat is nice because it allows copying only some Django template input variables to Javascript and server-side code does not need to know which data structures must be used by Javascript and hence converted to JSON before rendering the Django template. Either use this or always copy all Django variables to Javascript.
-
w0rp about 9 yearsPlease update this to include the |escapejs filter, otherwise you can end up with variables containing quote characters in the name and such, and this can lead to XSS attacks.
-
user1496984 almost 9 yearsSo the best solution is to use
var a = {{someDjangoVariable|escapejs|safe}}"
then? -
fiveclubs over 8 yearsNote that 'simplejson' became 'json' as of django 1.7, I believe.
-
James111 over 8 yearsIf it's something that won't alter a database or won't be sent to a database query this would be fine. @AndyL
-
Ciro Santilli OurBigBook.com almost 8 yearsBut note: stackoverflow.com/questions/23752156/…
-
the_unknown_spirit over 7 yearswhat if the javascript is written in a different file?
-
user2867288 about 7 yearsGuys... users can do what they want anyways. Browsers make it so easy nowadays with a fully featured DOM inspector and debugging tools. Moral of the story: do ALL you data validation on the server.
-
Jorge Orpinel Pérez almost 7 yearsNice. Is that the same as just using docs.djangoproject.com/en/1.10/ref/templates/builtins/#safe though?
-
Yaroslav Admin almost 7 years@JorgeOrpinel No, it is not same.
safe
only marks value as safe, without proper conversion and escaping. -
kbdev almost 7 yearsHow do you then display the variable in the django template?
-
Ahtisham over 6 yearsPlease can anyone tell me how would you access that variable in an external JavaScript file ? but a secure way.
-
Ahtisham over 6 yearsPlease can anyone tell me how would you access that variable in an external JavaScript file ?
-
Sahand over 6 yearsAhtisham, you get it by doing what bosco- did:
var myVar = document.getElementById("myVar").value;
. This will work if the javascript is executed on the same page as the hidden input element. -
Sahand over 6 years@YaroslavAdmin, isn't it a problem that this solutions requires one to always keep the javascript in the template file? Most of the projects I've seen keeps the javascript in a separate js-folder. I tried you solution and it doesn't work with the js in a separate folder.
-
Yaroslav Admin over 6 years@Sandi back when I posted it it was common to have a widget in separate JS file and initialize it in the page source code. So let's say you declare
function myWidget(config) { /* implementation */ }
in JS file and than you use it on some pages usingmyWidget({{ pythonConfig | js }})
. But you can not use it in JS files (as you noticed), so it has its limitations. -
Jon Sakas over 5 years10 years later and Django has introduced a built in template filter just for this: docs.djangoproject.com/en/2.1/ref/templates/builtins/…
-
Mohith7548 almost 5 yearsI have Django template for creating a button with id in html tag = name of the object
id="{{ obj.name }}
. Now how to refer to this id by JS? Doing this is giving me error.var c = document.getElementById({{ obj.name }});
-
pcworld over 4 yearsDon't use this, it's vulnerable to XSS (script injection). For instance an attacker could inject
</script>
into the data, thus breaking out of the current script and injecting arbitrary HTML (including starting a new script with<script>
). -
pcworld over 4 yearsDon't use this, it's vulnerable to script injection (XSS).
-
derteufelqwe over 3 yearsThis should actually be the answer. This works perfectly without any weired manual quote escaping.
-
logicOnAbstractions almost 3 yearsBest answer in 2021 overall. Jon Saks provided the same however didn't include actual code in the answer, only links to docs (links break, change, move....)
-
Yi Zong Kuang over 2 yearsIf you have double quotes or single quotes in your
someDjangoVariable
, it's better to do thisvar a = `{{someDjangoVariable|safe}}`;
. Or if it's JSON content in yoursomeDjangoVariable
, it's might be best to just dovar a = {{someDjangoVariable|safe}};
, this way Javascript will load the JSON correctly