4

I am referring to the answer in the question listed below as I am trying to run a query that gets the closest object to a given point in my django application. My django version is 1.9.2.

How to return a record with the lowest distance from a point using geodjango?

In my view I am passing in a Zipcode and using GeoPy to get the location and lat/long.

from django.contrib.gis.geos import *
from django.contrib.gis.measure import D
from geopy.geocoders import Nominatim

geolocator = Nominatim()

zipcode = self.request.query_params.get('zipcode', None)
distance_m = 20000

if zipcode is not None:
    location = geolocator.geocode(zipcode, timeout=None)
    origin = Point((location.latitude, location.longitude))

    queryset = Chapter.objects.filter(location__distance_lte=(origin, D(m=distance_m))).distance(origin).order_by('distance')[:1][0] 
    return queryset

The Chapter model has a field called location which is a point field.

from django.contrib.gis.db import models

class Chapter(models.Model):
    name = models.CharField(max_length=500)
    school = models.ForeignKey(School)
    verification = models.CharField(max_length=50)
    address1 = models.TextField()
    address2 = models.TextField(null=True, blank=True)
    city = models.TextField()
    state = models.TextField()
    zipcode = models.CharField(max_length=5)
    location = models.PointField(srid=4326, null=True, blank=True)
    is_school = models.BooleanField(default=False)
    is_association = models.BooleanField(default=False)
    authorized = models.NullBooleanField(default=False)
    stripe_account_active = models.NullBooleanField(default=False)

    def __unicode__(self):
        return self.name

    def get_nickname(self):
        return self.school.nickname

I get the following error when this executes:

AttributeError: 'QuerySet' object has no attribute 'distance'

Edit--

When I try to get the distance using the alternate method in the questions above I get a different error which makes me think there is something wrong with my model.

point = Chapter.objects.get(name='Chapter of the Year').location
distance_m = 20000

for chapter in Chapter.objects.distance(point):
    print(chapter.name, chapter.distance)

Error:

'Manager' object has no attribute 'distance'
Community
  • 1
  • 1

2 Answers2

6

Got this to work

Chapter.objects.filter(location__distance_lte=(origin, D(m=distance_m))).annotate(distance=Distance('location', origin)).order_by('distance')[:1][0] 
2

As written in this line :

queryset = Chapter.objects.filter(location__distance_lte = (origin, D(m=distance_m))).distance(origin).order_by('distance')[:1][0] 

You are ordering the result by distance but that is not a field/attribute in Chapter model. I think what you want is order by location__distance, so the actual filter query should be:

queryset = Chapter.objects.filter(location__distance_lte= (origin, D(m=distance_m))).distance(origin).order_by('location__distance')[:1][0] 

Also this line is totally incorrect :

for chapter in Chapter.objects.distance(point):

Because here, distance is not a method like filter or get. It should be something like that :

point = Chapter.objects.get(name='Chapter of the Year')
distance_m = 20000

for chapter in Chapter.objects.filter(id = point.id ):
    print(chapter.name, chapter.location.distance)
Prakhar Trivedi
  • 8,218
  • 3
  • 28
  • 35
  • 1
    I just tried this and its still not working. I just added some additional context to the question after trying to loop through and get the distance for each instance. – Brandon Mitchell May 06 '17 at 09:34
  • @BrandonMitchell The problem with both conditions are the same. **Chapter** model does not have a field/ attribute named **distance**. – Prakhar Trivedi May 06 '17 at 09:41
  • @BrandonMitchell Please add the code of model **Chapter** also in the question. That will help in solving the problem. – Prakhar Trivedi May 06 '17 at 09:42
  • @BrandonMitchell You can notice from the question from where you are taking help, that answer does not mention anything about this method. It was Op's mistake in that question also. – Prakhar Trivedi May 06 '17 at 09:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143564/discussion-between-prakhar-trivedi-and-brandon-mitchell). – Prakhar Trivedi May 06 '17 at 10:11
  • Still trying to get the queryset to return the closest location. – Brandon Mitchell May 06 '17 at 10:30