2

I am passing a python dictionary to a Django template html script as:-

def create_dict(request):
   #creating the dictionary and storing it in py_dict
   py_dict = json.dumps(py_dict)
   context = {
   "py_dict": py_dict
   }
   render(request, 'index.html', context)

In the Django template (index.html), I am retrieving the dictionary as follows:-

 <script language='javascript'>
        $(document).ready(function(){
        var dict = "{{py_dict}}";
        console.log(dict);
        });
</script>

If I try to assign the variable dict directly the Django variable(py_dict) without the double qoutes(var dict = {{py_dict}};) then it shows Not found & error

The actual python dictionary looks like this:-

{"19.2.000/": {"19.2.000/dataconversion/": {}, "19.2.000/reim/": {}, "19.2.000/resa/": {}, "19.2.000/rms/": {}}, "19.2.001/": {"19.2.001/dataconversion/": {}}, "19.2/": {"19.2/alloc/": {}, "19.2/rpm/": {}}, "RESA/": {"RESA/folder1/": {}}, "RMS/": {}, "RPM/": {}, "/": {}, "apc/": {"apc/apc_inner/": {}}, "dataconversion/": {}, "folder2/": {}, "merch/": {"merch/19.0.x/": {"merch/19.0.x/19.0.000.1/": {"merch/19.0.x/19.0.000.1/dataconversion/": {}}, "merch/19.0.x/19.0.001/": {"merch/19.0.x/19.0.001/alloc/": {}, "merch/19.0.x/19.0.001/reim/": {}, "merch/19.0.x/19.0.001/resa/": {}, "merch/19.0.x/19.0.001/rms/": {"merch/19.0.x/19.0.001/rms/reports/": {}}, "merch/19.0.x/19.0.001/rpm/": {}}, "merch/19.0.x/19.0.002.1/": {"merch/19.0.x/19.0.002.1/Merged_RC/": {"merch/19.0.x/19.0.002.1/Merged_RC/rms/": {}}, "merch/19.0.x/19.0.002.1/hotfix/": {"merch/19.0.x/19.0.002.1/hotfix/rms/": {}}}, "merch/19.0.x/19.0.002/": {"merch/19.0.x/19.0.002/alloc/": {}, "merch/19.0.x/19.0.002/dataconversion/": {}, "merch/19.0.x/19.0.002/jos_merch/": {}, "merch/19.0.x/19.0.002/reim/": {}, "merch/19.0.x/19.0.002/resa/": {}, "merch/19.0.x/19.0.002/rms/": {"merch/19.0.x/19.0.002/rms/rms19installer.zip": {}}}}}}

but when I console.log it in the script tag, the output is this:-

{&quot;19.2.000/&quot;: {&quot;19.2.000/dataconversion/&quot;: {}, &quot;19.2.000/reim/&quot;: {}, &quot;19.2.000/resa/&quot;: {}, &quot;19.2.000/rms/&quot;: {}}, &quot;19.2.001/&quot;: {&quot;19.2.001/dataconversion/&quot;: {}}, &quot;19.2/&quot;: {&quot;19.2/alloc/&quot;: {}, &quot;19.2/rpm/&quot;: {}}, &quot;RESA/&quot;: {&quot;RESA/folder1/&quot;: {}}, &quot;RMS/&quot;: {}, &quot;RPM/&quot;: {}, &quot;/&quot;: {}, &quot;apc/&quot;: {&quot;apc/apc_inner/&quot;: {}}, &quot;dataconversion/&quot;: {}, &quot;folder2/&quot;: {}, &quot;merch/&quot;: {&quot;merch/19.0.x/&quot;: {&quot;merch/19.0.x/19.0.000.1/&quot;: {&quot;merch/19.0.x/19.0.000.1/dataconversion/&quot;: {}}, &quot;merch/19.0.x/19.0.001/&quot;: {&quot;merch/19.0.x/19.0.001/alloc/&quot;: {}, &quot;merch/19.0.x/19.0.001/reim/&quot;: {}, &quot;merch/19.0.x/19.0.001/resa/&quot;: {}, &quot;merch/19.0.x/19.0.001/rms/&quot;: {&quot;merch/19.0.x/19.0.001/rms/reports/&quot;: {}}, &quot;merch/19.0.x/19.0.001/rpm/&quot;: {}}, &quot;merch/19.0.x/19.0.002.1/&quot;: {&quot;merch/19.0.x/19.0.002.1/Merged_RC/&quot;: {&quot;merch/19.0.x/19.0.002.1/Merged_RC/rms/&quot;: {}}, &quot;merch/19.0.x/19.0.002.1/hotfix/&quot;: {&quot;merch/19.0.x/19.0.002.1/hotfix/rms/&quot;: {}}}, &quot;merch/19.0.x/19.0.002/&quot;: {&quot;merch/19.0.x/19.0.002/alloc/&quot;: {}, &quot;merch/19.0.x/19.0.002/dataconversion/&quot;: {}, &quot;merch/19.0.x/19.0.002/jos_merch/&quot;: {}, &quot;merch/19.0.x/19.0.002/reim/&quot;: {}, &quot;merch/19.0.x/19.0.002/resa/&quot;: {}, &quot;merch/19.0.x/19.0.002/rms/&quot;: {&quot;merch/19.0.x/19.0.002/rms/rms19installer.zip&quot;: {}}}}}}

in which &quot; is added for every " and obviously it is not in the actual JSON format which javascript can process. And also since I am passing the Django variable (py_dict) inside double quotes to the variable dict that itself is also a problem since it becomes a string variable due to which I cannot perform any actions on the elements of the Django variable dictionary py_dict

How do I convert this into a proper javascript JSON format?

2
  • Try to use var dict = {{ py_dict | safe }}; Commented Apr 19, 2021 at 8:56
  • Great, i added it as an official reply. Commented Apr 19, 2021 at 9:04

2 Answers 2

10

As a rule of thumb never render anything from Django directly inside javascript. This can lead to potential XSS attacks. If you want data from the server either use AJAX if it is needed dynamically or you can use the json_script template filter [Django docs] if it is needed only once when the page gets loaded:

Somewhere in the HTML:

{{ py_dict|json_script:"py_dict" }}

This will render like:

<script id="py_dict" type="application/json">JSON HERE</script>

Next in javascript you can simply use:

var dict = JSON.parse(document.getElementById('py_dict').textContent);
Sign up to request clarification or add additional context in comments.

4 Comments

this works, but JSON.parse gives a string instead of object
@AmithM you should pass a python object to json_script not something that is already serialized into a JSON string.
i did pass a python dictionary, and still the same result, i had to replace <singlequote> to <doublequote> on document.getElementById('py_dict').textContent for it to work. JSON.parse(document.getElementById('py_dict').textContent.replace("'", '"'));
nvm i am dumb, i was passing a str(dict), thanks!
3

Instead of

var dict = "{{py_dict}}";

you can simply use:

var dict = {{ py_dict | safe }};

You can check the safe template tag here https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#safe

2 Comments

What you do is vulnerable to XSS attacks. There is a reason why Django makes it hard to do these things...
how it is vulnerable to XSS attack? could you please explain?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.