Reputation: 55
I've been banging my head against the wall trying to figure out why I can't pass a JSON string generated from a Django Model into a template's javascript static file. As it turns out, the problem wasn't at the Model level (using serializers.serialize) - putting an identical string in the script itself will successfully parse, but passing the string in will not:
views.py:
def texas(request):
test_json = '{"incidents": [{"field1": 1, "field2": 2}], "debug": 1}'
return render(request, 'tx/texas.html', {'tx': test_json})
tx/texas.html:
{% load staticfiles %}
<html>
<head>
<title>texas map</title>
</head>
<body>
<p id='texas'></p>
<script>
function load_texas() {
return '{{ tx }}';
}
</script>
<script src="{% static 'js/texas.js' %}"></script>
</body>
</html>
js/texas.js fails with JSON.parse: expected property name or '}' at line 1 column 2 of the JSON data:
var json_data = load_texas();
var paragraph = document.getElementById('texas');
try {
paragraph.innerHTML = JSON.parse(json_data);
}
catch(err) {
paragraph.innerHTML = err.message;
}
but is successful if the same string is just entered in the script:
// this JSON string is identical to the one passed in views.py
var json_data = '{"incidents": [{"field1": 1, "field2": 2}], "debug": 1}';
Am I missing something about the way Django handles context variables?
Not quite a fix for passing a string, but I'm now passing a JSON object directly to the template which solves my original problem of getting Models into javascript.
views.py:
from django.shortcuts import render
from django.core import serializers
import json
from .models import Tx
def texas(request):
tx_database = Tx.objects.all()
# Django serialize puts square brackets around the string,
# so slice them off.
json_string = serializers.serialize('json', tx_database)[1:-1]
# Load string into JSON object... is this best practice?
test_json = json.loads(json_string)
return render(request, 'tx/texas.html', {'tx': test_json})
Upvotes: 3
Views: 5238
Reputation: 600059
You need to disable autoescaping.
return '{{ tx|safe }}';
Note, you really should not create JSON data as strings in your view; create it as a Python datastructure, then use json.dumps()
.
Upvotes: 3