[javascript] 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.

The answer is


For a JavaScript object stored in a Django field as text, which needs to again become a JavaScript object dynamically inserted into on-page script, you need to use both escapejs and JSON.parse():

var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}");

Django's escapejs handles the quoting properly, and JSON.parse() converts the string back into a JS object.


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.


new docs says use {{ mydata|json_script:"mydata" }} to prevent code injection.

a good exmple is given here:

{{ mydata|json_script:"mydata" }}
<script>
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
</script>

I use this way in Django 2.1 and work for me and this way is secure (reference):

Django side:

def age(request):
    mydata = {'age':12}
    return render(request, 'test.html', context={"mydata_json": json.dumps(mydata)})

Html side:

<script type='text/javascript'>
     const  mydata = {{ mydata_json|safe }};
console.log(mydata)
 </script>

For a dictionary, you're best of encoding to JSON first. You can use simplejson.dumps() or if you want to convert from a data model in App Engine, you could use encode() from the GQLEncoder library.


There are two things that worked for me inside Javascript:

'{{context_variable|escapejs }}'

and other: In views.py

from json import dumps as jdumps

def func(request):
    context={'message': jdumps('hello there')}
    return render(request,'index.html',context)

and in the html:

{{ message|safe }}

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>

I have found we can pass Django variables to javascript functions like this:-

<button type="button" onclick="myJavascriptFunction('{{ my_django_variable }}')"></button>
<script>
    myJavascriptFunction(djangoVariable){
       alert(djangoVariable);
    }
</script>

new docs says use {{ mydata|json_script:"mydata" }} to prevent code injection.

a good exmple is given here:

{{ mydata|json_script:"mydata" }}
<script>
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
</script>

There are two things that worked for me inside Javascript:

'{{context_variable|escapejs }}'

and other: In views.py

from json import dumps as jdumps

def func(request):
    context={'message': jdumps('hello there')}
    return render(request,'index.html',context)

and in the html:

{{ message|safe }}

I've been struggling with this too. On the surface it seems that the above solutions should work. However, the django architecture requires that each html file has its own rendered variables (that is, {{contact}} is rendered to contact.html, while {{posts}} goes to e.g. index.html and so on). On the other hand, <script> tags appear after the {%endblock%} in base.html from which contact.html and index.html inherit. This basically means that any solution including

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

is bound to fail, because the variable and the script cannot co-exist in the same file.

The simple solution I eventually came up with, and worked for me, was to simply wrap the variable with a tag with id and later refer to it in the js file, like so:

// index.html
<div id="myvar">{{ myVar }}</div>

and then:

// somecode.js
var someVar = document.getElementById("myvar").innerHTML;

and just include <script src="static/js/somecode.js"></script> in base.html as usual. Of course this is only about getting the content. Regarding security, just follow the other answers.


Note, that if you want to pass a variable to an external .js script then you need to precede your script tag with another script tag that declares a global variable.

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

<script type="text/javascript" src="{% static "scripts/my_script.js" %}"></script>

data is defined in the view as usual in the get_context_data

def get_context_data(self, *args, **kwargs):
    context['myVar'] = True
    return context

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;

I've been struggling with this too. On the surface it seems that the above solutions should work. However, the django architecture requires that each html file has its own rendered variables (that is, {{contact}} is rendered to contact.html, while {{posts}} goes to e.g. index.html and so on). On the other hand, <script> tags appear after the {%endblock%} in base.html from which contact.html and index.html inherit. This basically means that any solution including

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

is bound to fail, because the variable and the script cannot co-exist in the same file.

The simple solution I eventually came up with, and worked for me, was to simply wrap the variable with a tag with id and later refer to it in the js file, like so:

// index.html
<div id="myvar">{{ myVar }}</div>

and then:

// somecode.js
var someVar = document.getElementById("myvar").innerHTML;

and just include <script src="static/js/somecode.js"></script> in base.html as usual. Of course this is only about getting the content. Regarding security, just follow the other answers.


I use this way in Django 2.1 and work for me and this way is secure (reference):

Django side:

def age(request):
    mydata = {'age':12}
    return render(request, 'test.html', context={"mydata_json": json.dumps(mydata)})

Html side:

<script type='text/javascript'>
     const  mydata = {{ mydata_json|safe }};
console.log(mydata)
 </script>

I have found we can pass Django variables to javascript functions like this:-

<button type="button" onclick="myJavascriptFunction('{{ my_django_variable }}')"></button>
<script>
    myJavascriptFunction(djangoVariable){
       alert(djangoVariable);
    }
</script>

For a JavaScript object stored in a Django field as text, which needs to again become a JavaScript object dynamically inserted into on-page script, you need to use both escapejs and JSON.parse():

var CropOpts = JSON.parse("{{ profile.last_crop_coords|escapejs }}");

Django's escapejs handles the quoting properly, and JSON.parse() converts the string back into a JS object.


you can assemble the entire script where your array variable is declared in a string, as follows,

views.py

    aaa = [41, 56, 25, 48, 72, 34, 12]
    prueba = "<script>var data2 =["
    for a in aaa:
        aa = str(a)
        prueba = prueba + "'" + aa + "',"
    prueba = prueba + "];</script>"

that will generate a string as follows

prueba = "<script>var data2 =['41','56','25','48','72','34','12'];</script>"

after having this string, you must send it to the template

views.py

return render(request, 'example.html', {"prueba": prueba})

in the template you receive it and interpret it in a literary way as htm code, just before the javascript code where you need it, for example

template

{{ prueba|safe  }}

and below that is the rest of your code, keep in mind that the variable to use in the example is data2

<script>
 console.log(data2);
</script>

that way you will keep the type of data, which in this case is an arrangement


I was facing simillar issue and answer suggested by S.Lott worked for me.

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}"
</script>

However I would like to point out major implementation limitation here. If you are planning to put your javascript code in different file and include that file in your template. This won't work.

This works only when you main template and javascript code is in same file. Probably django team can address this limitation.


For a dictionary, you're best of encoding to JSON first. You can use simplejson.dumps() or if you want to convert from a data model in App Engine, you could use encode() from the GQLEncoder library.


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!


I was facing simillar issue and answer suggested by S.Lott worked for me.

<script type="text/javascript"> 
   var a = "{{someDjangoVariable}}"
</script>

However I would like to point out major implementation limitation here. If you are planning to put your javascript code in different file and include that file in your template. This won't work.

This works only when you main template and javascript code is in same file. Probably django team can address this limitation.


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>

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;

There is a nice easy way implemented from Django 2.1+ using a built in template tag json_script. A quick example would be:

Declare your variable in your template:

{{ variable|json_script:'name' }}

And then call the variable in your <script> Javascript:

var js_variable = JSON.parse(document.getElementById('name').textContent);

It is possible that for more complex variables like 'User' you may get an error like "Object of type User is not JSON serializable" using Django's built in serializer. In this case you could make use of the Django Rest Framework to allow for more complex variables.


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!


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.


There is a nice easy way implemented from Django 2.1+ using a built in template tag json_script. A quick example would be:

Declare your variable in your template:

{{ variable|json_script:'name' }}

And then call the variable in your <script> Javascript:

var js_variable = JSON.parse(document.getElementById('name').textContent);

It is possible that for more complex variables like 'User' you may get an error like "Object of type User is not JSON serializable" using Django's built in serializer. In this case you could make use of the Django Rest Framework to allow for more complex variables.


For a dictionary, you're best of encoding to JSON first. You can use simplejson.dumps() or if you want to convert from a data model in App Engine, you could use encode() from the GQLEncoder library.


Note, that if you want to pass a variable to an external .js script then you need to precede your script tag with another script tag that declares a global variable.

<script type="text/javascript">
    var myVar = "{{ myVar }}"
</script>

<script type="text/javascript" src="{% static "scripts/my_script.js" %}"></script>

data is defined in the view as usual in the get_context_data

def get_context_data(self, *args, **kwargs):
    context['myVar'] = True
    return context

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to django

How to fix error "ERROR: Command errored out with exit status 1: python." when trying to install django-heroku using pip Pylint "unresolved import" error in Visual Studio Code Is it better to use path() or url() in urls.py for django 2.0? Unable to import path from django.urls Error loading MySQLdb Module 'Did you install mysqlclient or MySQL-python?' ImportError: Couldn't import Django Django - Reverse for '' not found. '' is not a valid view function or pattern name Class has no objects member Getting TypeError: __init__() missing 1 required positional argument: 'on_delete' when trying to add parent table after child table with entries How to switch Python versions in Terminal?

Examples related to google-app-engine

Problems with installation of Google App Engine SDK for php in OS X Get Public URL for File - Google Cloud Storage - App Engine (Python) Visual Studio Code pylint: Unable to import 'protorpc' Get root password for Google Cloud Engine VM Spring Boot - Cannot determine embedded database driver class for database type NONE What is the difference between Google App Engine and Google Compute Engine? Cross-Origin Request Blocked Class JavaLaunchHelper is implemented in both. One of the two will be used. Which one is undefined ImportError: No module named apiclient.discovery java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer

Examples related to django-templates

Django - Did you forget to register or load this tag? How to add url parameters to Django template url tag? bootstrap 3 wrap text content within div for horizontal alignment Django, creating a custom 500/404 error page How can I get the username of the logged-in user in Django? Does Python have a toString() equivalent, and can I convert a db.Model element to String? How do I call a Django function on button click? What is the equivalent of "none" in django templates? Django - iterate number in for loop of a template Django -- Template tag in {% if %} block