Display Django queryset results on Google Map

I wanted to be able to show locations by latitude and longitude with data from Django 1.8 website on a Google Map using the Google Maps API.

I used the accepted answer from a stackoverflow question to create a Google Map with multiple markers that had the store name with a link that would open that store’s details when clicked.

I did the following:

  • copied the stackoverflow solution javascript and html code into new Django template called fountain_map.html
  • created new Django view called fountain_map for that template
  • create new urls.py line to route the fountain_map url for new view/template

The stackoverflow answer used Google Maps javascript that had a javascript array like this:

    var locations = [
      [‘Bondi Beach’, -33.890542, 151.274856, 4],
      [‘Coogee Beach’, -33.923036, 151.259052, 5],
      [‘Cronulla Beach’, -34.028249, 151.157507, 3],
      [‘Manly Beach’, -33.80010128657071, 151.28747820854187, 2],
      [‘Maroubra Beach’, -33.950198, 151.259302, 1]
    ];

However while the example has this hard coded list of locations I wanted a dynamic list populated by queryset records from the new view.

So I created a queryset in the view that retrieved the location records:

    map_points = Fountains.objects.filter(lat__isnull=False)

Note that I filtered to only retrieve records that had a lat value so I wasn’t sending records that couldn’t be mapped.

Since the queryset object is not immediately readable by the javascript as the location variable, it needed to be transformed into a format acceptable for the javascript.

There are a couple of options:

  • Use Django’s serialization to turn it into JSON
  • Loop through queryset object and manually build the array in correct format, this could be done in the view or in the template

I choose to do this transformation in the template. Django’s serialization has lots of documentation and lots of SO question and answer but seemed easier to do this in template for now.

So in the template i simply looped through the map_point queryset object to create the array that the var locations required.

The javascript required the square brackets as shown in example above along with quotes around the location name.

Note that the Stack Overflow answer also has a digit as the fourth item in the record but I excluded that in mine. Not sure what it was but user obviously wanted to show it in marker label or something like that.

Anyways my template loop looked like this:

        var locations = [
        {% for point in map_points %}
            {% if point.lat = None %}
            {% else %}
                [‘{{ point.name }}’, {{ point.lat }}, {{ point.lon }}],
            {% endif %}
        {% endfor%}
        ]

You can see that I retrieved the following values for the locations array from the queryset results:

  • name (fountain name to show on marker label popup)
  • id (so that it could be used to create marker link to the Django view for that store)
  • lat
  • lon

That was all I needed to do and gave me a Google Map showing each fountain’s location with a Google red pin marker. When user clicked on marker, the fountain name would show that had link to that fountain’s detail page.

google map

4 Thoughts on “Display Django queryset results on Google Map

  1. Hi Curtis, There are surprisingly few understandable replies in this context in reference to django, so I am trying to follow yours. I have done all the steps up until you moving things over to the model, i.e. copying out the script from the accepted answer, creating the views and urls – I get the map to show on the screen, however none of the markers are populating. What additional changes did you need to make to the script in order to have it work from within the django/html template framework? Thanks.

    • Curtis on May 6, 2017 at 4:02 pm said:

      My reply is a bit late but here are some troubleshooting steps.

      First verify that Django is actually creating any dataset at all, and if it is, is it actually the correct dataset eg does it have fields in expected order, with field names as expected? Is the query returning dataset with zero rows?

      Then verify that the template is actually getting the dataset and that it is able to use the data correctly. Is dataset named correctly, is the template looping through dataset in a way that returns results?

      Then verify that the Maps Javascript is actually getting the dataset and able to use it.

      To verify results simply either print out results using Python or Javascript and view results in your web browser developer pane.

      Key thing is to move methodically step by step of the way to zero in on where the issue is.

  2. Brian on June 10, 2017 at 3:56 am said:

    Hi Curtis, thanks for this. Have you been able to populate markers with a queryset and get ‘info windows’ to work properly? All of the tutorials I’ve seen use a static set of marker locations with static info window content which works ok…but looping (i++’ing) through queryset results does not seem to work. Any thoughts?

  3. Curtis on August 24, 2017 at 11:49 pm said:

    Hey Brian. My example above does just what you describe. The locations are result from Django queryset. I loop through queryset in template to populate a Google Maps javascript variable that contains an array with all fountains (eg their names, url to its page in my site, and its lat and lon).

    The Google Maps javascript then loops through the array. This is same loop that examples have, instead it loops through the static array hard coded in the example. In my case, I use Django template to create that array. The key thing is to make the array variable in correct format.

    I created the array variable named “locations” above, which creates something like this in when the page is viewed eg when template is run.

    var locations = [
    ['Fountain 1 name', 49.279504, -123.1162],
    ['Fountain 2 name', 49.278868, -123.1149],
    ]

    This is done within the Google Maps javascript so the variable is available to the javascript to use as follows. I am pretty sure the javascript below is same as Google Maps examples.


    -- start Google Maps javascript

    var locations = [
    ['Fountain 1 name', 49.279504, -123.1162],
    ['Fountain 2 name', 49.278868, -123.1149],
    ]

    var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(49.279504, -123.1162),
    zoom: 14,
    mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(locations[i][1], locations[i][2]), map: map, icon: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png' }); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { infowindow.setContent(locations[i][0]); infowindow.open(map, marker); } })(marker, i)); } -- end Google Maps javascript

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Post Navigation