2

I am trying to parse a JSON object to Django template so that I can parse this json object to javascript.

Here how my view creates and parse the json object to the template:

    countries = Country.objects.filter(Enabled=True)
    citiesByCountry = {}

    for country in countries:
        citiesInCountry = City.objects.filter(Enabled=True, Country=country)
        cities = []

        for city in citiesInCountry:
            cities.append(city.Name)

        citiesByCountry[country.Name] = cities

    context = {'citiesByCountry': json.dumps(citiesByCountry)}
    return render(request, 'index.html', context)

Now I would like to retrieve all the keys (which will be countries) to my template this way:

{% for country in citiesByCountry%}
   <option>{{ country }}</option>
{% endfor %}

But what I get is an option for each character in strings instead of the country name as a whole.

I tried to use .item1 but this didn't work either.

I don't show JavaScript code in my example above as the intent of the question is how to parse and retrieve strings from a JSON object. I need to process this data using javascript later. In specific once the user change country I would like to populate another dropdown that will handle the cities, and therefore I thought to use JSON and Javascript to achieve that, as I don't want to refresh the page on each change.

Any help?

5
  • 2
    Why do you need to parse it to javascript? In your example you are not doing that Commented Jul 11, 2016 at 10:15
  • Why are you encoding citiesByCountry to JSON? Just pass it as a dict to context like context = {'citiesByCountry': citiesByCountry} and it should work. Commented Jul 11, 2016 at 10:18
  • Thanks for the replies. I don't show JavaScript code in my example above as the intent of the question is how to parse and retrieve strings from a JSON object. I need to process this data using javascript later. In specific once the user change country I would like to populate another dropdown that will handle the cities, and therefore I thought to use JSON and Javascript to achieve that, as I don't want to refresh the page on each change. Commented Jul 11, 2016 at 10:20
  • @xyres I did what you said and works in the past, but now that I want to populate the city dropdown list using JavaScript, I am not sure if I can parse a Python List to javascript. Commented Jul 11, 2016 at 10:21
  • @John In that case, Django's template syntax won't work. You'll have to do it completely in JS. Commented Jul 11, 2016 at 10:23

3 Answers 3

4

To answer you question in the title:

In <head> (or somewhere), build your array of counties:

<script>
    var country_objs = [];
    {% for country in citiesByCountry%}
        country_objs.push({{country|escapejs}});
    {% endfor %}
<\script>

Docs for the filter: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/#escapejs

Then you can use it in JavaScript (but not in Django template). For example:

<select id="cities"><\select>
<script>
    var $cities_select = $("#cities");
    $(country_objs).each(function(){
        $cities_select.append('<option value="' + this.id_or_something + '">' + this.name + '<\option>');
    });
<\script>

But from your example I don't see why you need to encode it in JSON in the first place. Why not just pass a dict into the template (via context, just as everything else)?

P.S. Sorry for using jQuery, l'm just lazy :)

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

3 Comments

@John Ah, comments contain additional explanation about why JSON. Perhaps make an edit to your question. For future generations, you know ;)
Thanks. I have updated my question. I will give a try to your solution and I will let you know.
I think that worked. But for some reason the city value is 'Undefined' which I guess has something to do with this line $cities_select.append('<option>' + this.Name + '<\option>');
1

I think you have two options:

  1. Parse the JSON in the <option> tags with javascript.

    <script>
        var json = JSON.parse({{citiesByCountry}});
        //Loop through json and append to <option>
    </script>
    
  2. Add an extra context that isn't JSON serialized. This is a little redundant but a bit simpler.

    context = {'citiesByCountry_json': json.dumps(citiesByCountry), 'citiesByCountry': citiesbyCountry}
    

To be honest, I'd go for the second option since I don't see why you need to send it to the template in JSON in the first place.

Comments

1

When you do citiesByCountry = json.dumps({'a': "b", 'c': None}), citiesByCountry is a string. This is why you get character after character when you iterate over it.

This string representing a JSON object, you can "affect" as-is to a JavaScript variable:

var citiesByCountry = {{ citiesByCountry }};

Which will output something like:

var citiesByCountry = {"a": "c", "d": null};

However, considering what you want to achieve:

In specific once the user change country I would like to populate another dropdown that will handle the cities

I highly recommend you to checkout django-autocomplete-light, which in addition to providing auto-completion, provides a way to filter results based on other fields. This will save you much efforts.

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.