8

I have passed to template regular Python dictionary and I need to inside

$(document).ready(function() {.. }

to convert that Python dictionary to JavaScript dictionary. I tried like

var js_dict={{parameters}};

but I got errors ( ' instead of ' and all strings start with u' ). How can I convert Python dictionary to JavaScript hash table ?

1
  • Have you checked if there's a JSON.stringify equivalent in python? Commented Apr 9, 2012 at 13:01

8 Answers 8

20

Python and javascript both have different ideas about how to represent a dictionary, which means that you need a intermediate representation in order to pass data between them. The most common way to do this is JSON, which is a simple lightweight data-interchange format.

Use the python json library to convert (or dump) your python dict into a JSON string. Then in the javascript parse the JSON string into a javascript dict. (If you are using JQuery, then use jQuery.parseJSON)

Sign up to request clarification or add additional context in comments.

Comments

7

You could convert it to JSON and use that in that template

In your python code do

import json
...
...
return {'parameters': json.dumps(parameters)} #This data goes into your template

Comments

3

You can use json.dumps(parameters) with mark_safe()

def custom_view(request):
    ...
    return render(request, 'tmpl.html', {'parameters': mark_safe(json.dumps(parameters))})

With mark_safe() I get unescaped code in template.

Comments

3

I have found that this helps for strings that contain [ ' ] as well

const convertPythonDictToJSON = function (data) {
    let d = data.replace(new RegExp(`(?<=[a-zA-Z])'(?=[a-zA-Z ])`, "g"), '__')
    d = d.replace(new RegExp("'", 'g'), '"')
    d = d.replace(new RegExp("__", 'g'), "'")
    d = d.replace(new RegExp("None", 'g'), 'null')
    d = d.replace(new RegExp("False", 'g'), 'false')
    d = d.replace(new RegExp("True", 'g'), 'true')
    return JSON.parse(d)
}

3 Comments

Breaks for example {'notes': "1950's"} when ' is inside ".
I'd also have used the word boundary assertion \b around None and False and True: /\bNone\b/g for example, to avoid replacing those keywords inside strings. Not foolproof of course but...
I'd also have generated a random string for the ' placeholder instead of __, a bit more robust.
1

As others have already suggested, converting your dictionary to JSON in your view and then passing the JSON to the template context instead is really your best approach, but if you want to keep it as a python dictionary in your template, you can; you just need to manually create the javascript version (i.e. you can't just dump it with {{ parameters }})

<script>
    var js_dict = {
        {% for k, v in parameters %}
        "{{ k }}": "{{ v }}"{% if not forloop.last %},{% endif %}
        {% endfor %}
    }
</script>

Comments

1

A working example inspired by Chris Patt's answer below (note the difference):

 42     var js_dict = [
 43         {% for k, v in parameters.iteritems %}
 44             ["{{ k }}","{{ v }}"] {% if not forloop.last %},{% endif %}
 45         {% endfor %}
 46     ];

The default python's json lib doesn't seem to work for me when dealing with variables in template in Django.

Comments

0

You don't need to send the dictionary.

Here is how I implemented this:

views.py

def mess_opi(request):
    data = Opi_calculated.objects.all()

return render(request,'hab_app/opi_student_portal.html', {'data': data})

my template(for morris.html):

data: [{% for item in data %}
    { "y": '{{ item.hostelName }}', "a": '{{ item.opi_value }}' }{% if not forloop.last %},{% endif %}
{% endfor %}],

Comments

0

How handled this case by passing object on template page instead on passing the dict from py file and i created the required dict on template itself. like:

on my py:

def abc(request): 
     conf = assessment_master.objects.all()
     return render(request, "enter_scheme.html", {'conf':conf})

on my django template: within my script tag:

<script>
           var conf_dict_list = {};
           {% for obj in conf_dict_list %}
               conf_dict_list["{{ obj.short_name }}"] = "{{ obj.select }}"
           {% endfor %}

            alert(JSON.stringify(conf_dict_list));
            // alert('key' in conf_dict_list); to check key is present in dict

</script>

Comments

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.