I am trying to pass the following context from views.py to a Django Template:
views.py:
def home(request):
context = {
'dict_1': {'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']}
}
return render(request, 'app/home.html', context)
home.html:
<script type="text/javascript">
var java_dict = {{ dict_1 }};
console.log(java_dict);
</script>
This throws an error: Uncaught SyntaxError: Unexpected token '&'
Upon investigating, I see that the dictionary in javascript is read as follows:
{'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']}
which probably means that the quotes-character (') is read incorrectly. How do I fix this issue?
The context data that you pass into Django templates are escaped by default, for security purposes.
If you're sure that the data is safe, you can do this:
views.py
import json
def home(request):
# Use JSON dump so that it will be a data that can be loaded in javascript
context = {
'dict_1': json.dumps({
'key_1': ['val_11', 'val_12'], 'key_2': ['val_21', 'val_22']
})
}
return render(request, 'app/home.html', context)
home.html
<script type="text/javascript">
var java_dict = {{ dict_1| safe }}; // Actually solve your problem. Don't escape the data.
console.log(java_dict);
</script>
By default, all values in Django templates escape HTML characters for security purposes. If you want to use this dictionary in JavaScript you should use json_script filter. Please read the docs to understand what's going on.
A solution for your problem would be to:
Add the script tag containing your dict to the template
{{ dict_1 |json_script:"ID_OF_NEW_SCRIPT_TAG" }}
Load the dict value in your script tag (I'll use the name you had in your example)
var java_dict = JSON.parse(document.getElementById('ID_OF_NEW_SCRIPT_TAG').textContent);
console.log(java_dict);
Replace ID_OF_NEW_SCRIPT_TAG with whatever ID makes sense to you.
Related
I'm aware that a lot of people asked a similiar question, but none of these helped me with my problem!? Inside my view I'm passing the name of the active user...
views.py
def index(request):
user = User.objects.get(username=request.user)
user_name = f"{user.first_name} {user.last_name}"
json_data = json.dumps(user_name)
return render(request, 'index.html', {"user_name": json_data})
script.js
let user_name = {{user_name|safe}};
But when trying to attach the data to my variable inside javascript, I'm getting the following error and all of my other functions inside js stop working!
SyntaxError: Unexpected token '{'
Does someone know what I'm doing wrong here?
Thanks for your help and have a great day!
Okay...dunno if this is a propper solution for my problem, but at least now it's working as it should! I'm passing the data into my index.html, so that I'm able to access it further down the line inside my script.js!
index.html
<script>
let username = {{ user_name|safe }};
</script>
<script type="text/javascript" src="{% static '...' %}"></script>
I am rendering the json response data through apiview in django restframework, to html template list.html where i want to retrieve this data in a javascript code.
However everytime it gives "missing ) after argument list error" even though they are not actually present in the data received (as seen in inspect tools of chrome)
Getting the error on
var list =JSON.parse("{{data|safe}}")
The code apiview from views.py which is rendering the data is :
#api_view(['GET','POST'])
def memeList(request):
if request.method=='GET':
meme = Meme.objects.all().order_by('-meme_id')[:100]
serializer = MemeSerializer(meme, many=True)
elif request.method=='POST':
serializer=MemeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
serJS = JsonResponse(serializer.data,safe=False)
return render(request,'list.html',{'data':serJS.content})
Any solution for this as i have tried all available solutions on the internet still the problem isn't resolved.
The problem lies in the last line in the snippet from your views.py file:
return render(request, 'list.html', {'data': serJS.content})
Here, serJS.content returns a bytestring representing the content. To parse it as JSON, you need to convert it to string, render in the html body and then it will be parsed as JSON correctly. Use this instead:
return render(request, 'list.html', {'data': serJS.content.decode()})
You cannot do this:
var list = JSON.parse("{{data|safe}}")
{{ data|safe }} will render Python objects that cannot be (reliably) parsed as JSON.
What you likely want is to use the json_script template filter. Follow the steps in the docs to get your data as JSON in JavaScript.
I am trying to pass a variable onto a javascript in flask.
But I get the following error: TypeError: Object of type MyClass is not JSON serializable
Code:
routes.py:
#app.route('/')
#app.route('/index')
def index():
data = {
"foo": myObj
}
return render_template('index.html', data=data)
To note that myObj is a custom class object of type MyClass.
index.html:
<script src="{{ url_for('static', filename='my_script.js', type="module") }}" crossorigin="anonymous"
defer>
</script>
<script>
let data = {{ data|tojson }};
</script>
my_script.js:
console.log(data);
I tried to simply write {{ data }} instead of {{ data|tojson }} but I get the errors:
Uncaught SyntaxError: Unexpected token '&' and my_script.js?type=module:1 Uncaught ReferenceError: data is not defined at my_script.js?type=module:1
I know that there are a lot of question, but I do not find one that addresses this issue.
The problem here is that you're trying to pass a Python object to Javascript. It's not going to work. The best thing to do is convert it to JSON, which is compatible between Python and Javascript.
Using the json module you can serialise your dictionary. However, the Python object of MyClass is not JSON serialisable. You should be able to serialise the __data__ attribute instead, which is a dictionary of attributes in the object.
Change your Python like this:
import json
#app.route('/')
#app.route('/index')
def index():
data = {
"foo": myObj.__dict__
}
return render_template('index.html', data=json.dumps(data))
I am trying to import a python dictionary from moodels and manipulate/print it's properties in Javascript. However nothing seems to print out and I don't receive any error warnings.
Views.py
from chesssite.models import Chess_board
import json
def chess(request):
board = Chess_board()
data = json.dumps(board.rep)
return render(request, 'home.html', {'board': data})
Here board.rep is a python dictionary {"0a":0, "0b":0, "0c":"K0"} - basically a chess board
home.html
<html>
<body>
{% block content %}
<script>
for (x in {{board}}) {
document.write(x)
}
</script>
{% endblock %}
</body>
</html>
I also would very much appreciate some debugging tips!
Thanks in advance, Alex
Django defaults to escaping things as HTML, and that will make " into #quot;. Try changing {{board}} into {{board|safe}} to prevent the html escaping. Alternatively, in the view you can wrap the string in mark_safe() which is in django.utils.safestring to indicate that the string shouldn't be escaped.
To transfer data between django and javascript, dump data in django view and load in a javascript variable. Try to avoid django interpolation with javascript language constructs. It is unsafe, error prone, and can cause complexities.
in view
data = json.dumps(board.rep)
in template
const data = JSON.parse('{{ data|safe }}')
// use normal javascript here. 'data' is a javascript array
for (let x of data) {
document.write(x)
}
I want to export a JSON string in python into a JS variable.
<script type="text/javascript">
var data = JSON.parse('{{ dataJSON }}');
console.log(data)
</script>
If I print the content of dataJSON I get: [{"offset":0,"total":1,"units":[{"village_id":37,"village_name":"Glim
But in the JS I get this: JSON.parse('[{"offset":0,"total":1,"units":[{"village_id":37
I use jinja2 template engine: http://jinja.pocoo.org/docs/dev/templates/#if
How can I fix that?
You need to mark the data as safe:
var data = {{ dataJSON|safe }};
This prevents it from being HTML-escaped. There is no need to use JSON.parse() this way; JSON is a valid JavaScript subset (at least insofar that the Python json module produces a valid subset).
Take into account that this doesn't make it JavaScript safe. You may want to adjust your JSON serialisation. If you are using Flask, a tojson filter is provided that ensures you get JavaScript-safe valid JSON:
var data = {{ data|tojson|safe }};
If you are not using Flask, post-process the JSON:
dataJSON = (json.dumps(data)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
This is Python code to produce a dataJSON value that can be safely used in HTML (including attribute values) and in JavaScript. Credit here goes to the Flask json.htmlsafe_dumps() function.