395
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 code.
89
Caution: Check ticket #17419 for a discussion on adding a similar tag into Django core and possible XSS vulnerabilities introduced by using this template tag with user generated data. A 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 JavaScript 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
.
Here is an example of a 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 a variable to a JSON string. You can use it like so:
// myapp/templates/example.html
{% load js %}
<script type="text/javascript">
var someVar = {{ some_var | js }};
</script>
- [Django]-Django-social-auth django-registration and django-profiles β together
- [Django]-What is "load url from future" in Django
- [Django]-Disabled field is not passed through β workaround needed
78
A solution that worked for me was 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;
- [Django]-Django: remove a filter condition from a queryset
- [Django]-PyCharm: DJANGO_SETTINGS_MODULE is undefined
- [Django]-South migration: "database backend does not accept 0 as a value for AutoField" (mysql)
57
As of Django 2.1, a new built-in template tag has been introduced specifically for this use case: json_script().
The new tag will safely serialize template values and will protect against XSS.
Django documentation excerpt:
Safely outputs a Python object as JSON, wrapped in a tag,
ready for use with JavaScript.
- [Django]-No module named pkg_resources
- [Django]-Getting Values of QuerySet in Django
- [Django]-How to change empty_label for modelForm choice field?
20
The new documentation says use {{ mydata|json_script:"mydata" }}
to prevent code injection.
A good example is given here:
{{ mydata|json_script:"mydata" }}
<script>
const mydata = JSON.parse(document.getElementById('mydata').textContent);
</script>
- [Django]-Django QuerySet order
- [Django]-Get user profile in django
- [Django]-Django: Multiple forms possible when using FormView?
19
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 code:
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.
- [Django]-Django-taggit β how do I display the tags related to each record
- [Django]-Charts in django Web Applications
- [Django]-Django: sqlite for dev, mysql for prod?
12
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.
- [Django]-Adding to the "constructor" of a django model
- [Django]-Paginate relationship in Django REST Framework?
- [Django]-Override existing Django Template Tags
10
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 JSON content: context['DJdata'] = json.dumps(DJdata)
- [Django]-Django: how save bytes object to models.FileField?
- [Django]-Login Page by using django forms
- [Django]-How to update an existing Conda environment with a .yml file
9
For a dictionary, youβre best off 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.
- [Django]-Django model constraint for related objects
- [Django]-Cross domain at axios
- [Django]-Django create userprofile if does not exist
7
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
- [Django]-Trying to migrate in Django 1.9 β strange SQL error "django.db.utils.OperationalError: near ")": syntax error"
- [Django]-On Heroku, is there danger in a Django syncdb / South migrate after the instance has already restarted with changed model code?
- [Django]-Django REST Framework β 405 METHOD NOT ALLOWED using SimpleRouter
6
I was facing a similar issue and an answer suggested by S.Lott worked for me.
<script type="text/javascript">
var a = "{{someDjangoVariable}}"
</script>
However, I would like to point out a 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.
- [Django]-How to show processing animation / spinner during ajax request?
- [Django]-Do I need Nginx with Gunicorn if I am not serving any static content?
- [Django]-How do I clone a Django model instance object and save it to the database?
5
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 coexist 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 JavaScript 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.
- [Django]-Django REST Framework: how to substitute null with empty string?
- [Django]-With DEBUG=False, how can I log django exceptions to a log file
- [Django]-How to resize the new uploaded images using PIL before saving?
5
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>
- [Django]-Getting Values of QuerySet in Django
- [Django]-Authenticate by IP address in Django
- [Django]-What is the difference between null=True and blank=True in Django?
4
I use this way in Django 2.1 and it works 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>
- [Django]-How to get username from Django Rest Framework JWT token
- [Django]-What does on_delete do on Django models?
- [Django]-How to check if a user is logged in (how to properly use user.is_authenticated)?
1
There were 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 content:
{{ message|safe }}
- [Django]-Where to put business logic in django
- [Django]-POST jQuery array to Django
- [Django]-What is more efficient .objects.filter().exists() or get() wrapped on a try
1
You can use the variables from views.py
in JavaScript, <script></script>
in Django Templates.
For example, if you pass the dictionary with persons
having a list of dictionaries from views.py
to Django Templates as shown below:
# "views.py"
from django.shortcuts import render
def test(request, id=None, slug=None):
persons = [
{'name':'John', 'age':36},
{'name':'David','age':24}
]
return render(request, 'index.html', {"persons":persons})
Then, you can use the variables in JavaScript, <script></script>
in Django Templates as shown below:
# "index.html"
<script>
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
</script>
Then, these results are displayed on console:
John 36
David 24
Be careful, if you use a JavaScriptβs variable and for
loop, unexpected results are displayed on console:
# "index.html"
<script>
let js_persons = "{{ persons }}"
for (let i = 0; i < js_persons.length; i++) {
console.log(js_persons[i]);
}
</script>
Of course, you can use comment
tag in JavaScript, <script></script>
in Django Templates as shown below:
# "index.html"
<script>
{% for person in persons %}
{% comment %}
console.log("{{ person.name }} {{ person.age}}");
{% endcomment %}
{% endfor %}
</script>
# "index.html"
<script>
{% comment %}
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
{% endcomment %}
</script>
# "index.html"
{% comment %}
<script>
{% for person in persons %}
console.log("{{ person.name }} {{ person.age}}");
{% endfor %}
</script>
{% endcomment %}
- [Django]-Django: For Loop to Iterate Form Fields
- [Django]-Python (and Django) best import practices
- [Django]-Django FileField upload is not working for me
0
You can assemble the entire script where your array variable is declared in a string, as follows,
File 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.
File views.py
return render(request, 'example.html', {"prueba": prueba})
In the template, you receive it and interpret it in a literary way as HTML 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.
- [Django]-Django: list all reverse relations of a model
- [Django]-Django multiple template inheritance β is this the right style?
- [Django]-Django β SQL bulk get_or_create possible?
0
There are various answers pointing to json_script
. Contrary to what one might think, thatβs not a one-size-fits-all solution.
For example, when we want to pass to JavaScript dynamic variables generated inside a for loop, itβs best to use something like data-attributes.
- [Django]-When saving, how can you check if a field has changed?
- [Django]-How to get username from Django Rest Framework JWT token
- [Django]-Unittest Django: Mock external API, what is proper way?
0
If you want to send a variable directly to a function by passing it as a parameter, then try this
<input type="text" onkeyup="somefunction('{{ YOUR_VARIABLE }}')">
As from previous answers, the security can be improved upon.
- [Django]-How do I match the question mark character in a Django URL?
- [Django]-Django model blank=False does not work?
- [Django]-How do I use django rest framework to send a file in response?