13

My Django objects have an attribute "City". I'm trying to get a list of cities and catch it in the template with Jquery (to use in a chart on the X axis).
My problem is that I can't get rid of the unicode and quote for a list.
(I manage to do it for one single value). Instead I'm stucked with this:
["[[u'Paris'], [u'Lyon']]"]

I've tried tons of things, included JSON. No success.

My view: (actually, one of many try..)

def barchart1(request):
    city_array =[]
    for i in [1,MyObject.objects.count()]:
        objet = get_object_or_404(MyObject, pk=i)

        cities = [objet.city.city_name]
        city_array.append(cities)

return render (request, 'plot3/plot_page.html', {"city_array" : city_array}) 

My JS:

<script type="text/javascript">
    var cities = ["{{ city_array }}"];
</script>

Here is how JS read the context sent by the view
["[[u'Paris'], [u'Lyon']]"]

Here is what I would like to get
['Paris', 'Lyon']

It MUST be something simple but I just couldn't figure out how to do it. Others posts don't deal with a list of string.

Any idea of what should I do?

xavier carbonel
  • 339
  • 1
  • 3
  • 8

1 Answers1

30

When you do {{ city_array }} in your template, your list is converted to a string. This is done by calling repr() on the list, which recursively calls repr() on its contents. Because your strings are unicode, you see those unicode literals, u'Paris'.

The "correct" way to do this is to encode your data to json, for example in your view:

import json
# ...
json_cities = json.dumps(city_array)
# ...
return render (request, 'plot3/plot_page.html', {"city_array" : json_cities})

and then do

var cities = {{ city_array|safe }};

in the template.

Please note: don't use this for user-controller data! See the XSS Cheat Sheet by OSWASP and the discussion on Django ticket 17419 for further information. To prevent XSS, you could use something like the SafeJSONEncoder from the django-cms project.

sk1p
  • 6,645
  • 30
  • 35
  • Perfect that worked! Actually, I tried something similar but I didn't put |safe. How does it work ? After 4 hours, your help was welcome! – xavier carbonel Jan 15 '14 at 23:46
  • 1
    The `safe` template filter is a way to disable Django's built-in HTML escaping, which is a way to prevent [XSS attacks](http://en.wikipedia.org/wiki/Cross-site_scripting). You can read more [in the documentation](https://docs.djangoproject.com/en/dev/topics/templates/#automatic-html-escaping), but at least keep this in mind: only use `safe` if you are absolutely sure that no untrusted user input will end up unescaped in the output (in this case, `json.dumps(...)` takes care of it for you). – sk1p Jan 15 '14 at 23:53
  • @sana I'm afraid I was wrong about XSS safety of `json.dumps` - please see the edit! – sk1p Oct 12 '15 at 16:06