Reputation: 1219
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?
Upvotes: 2
Views: 11536
Reputation: 12903
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 :)
Upvotes: 4
Reputation: 34922
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.
Upvotes: 1
Reputation: 6980
I think you have two options:
Parse the JSON in the <option>
tags with javascript.
<script>
var json = JSON.parse({{citiesByCountry}});
//Loop through json and append to <option>
</script>
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.
Upvotes: 1