[Fixed]-Getting a list from Django into Javascript as an array

23๐Ÿ‘

If you are absolutely certain your list is safe, (by that I mean it never, ever includes anything entered by a user), it is very simple.

In your view:

context={"my_list": ["item1", "item2"]}

In your template:

{{ my_list|safe }}

Renders as:

['item1', 'item2']

For example:

{{ my_list|safe }}.forEach(item => {
  console.log(item)
})

Impressively, if you pass a string with an apostrophe, Django automatically changes the quote types, so

context = {"my_list": ["item1", "it'em2"]}

renders as (note the double-quotes):

['item1', "it'em2"]

so

{{ my_list|safe }}.forEach

still works (tested on Django 3.2.6).

Even this works:

context = {"my_list": ["item1", "it'em\"2"]}

renders as:

['item1', 'it\'em"2']

so

{{ my_list|safe }}.forEach

still works.

However, as I said at the top, if your list might include input from a user, I still wouldnโ€™t trust this approach.

==

EDIT: Now this is the highest answer, I wanted to add a safer approach to make it easier to be fully safe. This is interesting from django-argonauts, although Iโ€™m not a security expert so couldnโ€™t confirm the approach:

@register.filter(is_safe=True)
def jsonify(json_object):
    """
    Output the json encoding of its argument.
    This will escape all the HTML/XML special characters with their unicode
    escapes, so it is safe to be output anywhere except for inside a tag
    attribute.
    If the output needs to be put in an attribute, entitize the output of this
    filter.
    """

    json_str = json.dumps(json_object)

    # Escape all the XML/HTML special characters.
    escapes = ["<", ">", "&"]
    for c in escapes:
        json_str = json_str.replace(c, r"\u%04x" % ord(c))

    # now it's safe to use mark_safe
    return mark_safe(json_str)

Then in the template:

{% load jsonify %}
{{ value|jsonify }}
๐Ÿ‘คChris

6๐Ÿ‘

In views you can make your object as a JSON object:

import json

mylistraw = [10,22,33,45]
mylist = json.dumps(mylistraw)
context = {''mylistjson': mylist}

Now you can use your object in JavaScript:

var mylist = JSON.parse("{{mylistjson}}")
๐Ÿ‘คStrategy Guru

3๐Ÿ‘

You can simply use tojson tag to convert python list to js array.

It will be like โ€“

var mylist = {{mylist|tojson}};
for(i = 0; i < mylist.length; i++){
    console.log(mylist[i])
};

Try it and let me know if any problem occurs.

๐Ÿ‘คPankaj Sharma

3๐Ÿ‘

Django has the json_script template tag that addresses XSS vulnerabilities by escaping the <, >, and & characters.

Django json_script docs here

๐Ÿ‘คarcanemachine

1๐Ÿ‘

In your case, a simple way is to send the list as string ','.join(mylist). And then in your templates, you could simply use split(',') in js.

views

mylist = [10,22,33,45]
context['mylist'] = ','.join([str(i) for i in mylist])

html & js

var mylist = document.getElementById("list").innerHTML;
mylist = mylist.split(',')
for(i = 0; i < mylist.length; i++){
    console.log(mylist[i])
};

Or in case your js is in the template as well

var mylist = '{{mylist}}'.split(',');
for(i = 0; i < mylist.length; i++){
    console.log(mylist[i])
};
๐Ÿ‘คLemayzeur

-1๐Ÿ‘

Set the list value in JavaScript and not HTML.

<script>
var mylist = {{mylist}};
for(i = 0; i < mylist.length; i++){
    console.log(mylist[i])
};
<\ script>

You need to do this in your HTML template file and not in an external JS file.

Leave a comment