2013-08-12 2 views
2

Я пытаюсь сделать запрос к базе данных, что дает мне 20 ближайших пользователей заказанных на расстоянии (так ближе всего первым) я делаю происходит некорректноorder_by («- расстояние») не работает, как ожидалось

distance_mi = 100 

origin = GEOSGeometry('SRID=4326;'+ 'POINT('+ str(user_profile.current_location.x)+' '+str(user_profile.current_location.y)+')') 

close_users = UserProfile.objects.exclude(user = user).filter(current_location__distance_lte=(origin, D(mi=distance_mi))).distance(origin).order_by('-distance')[:20] 

но это возвращает обратно 3 пользователя (это правильно), но первый пользователь находится в 0 милях, второй - в 8 милях, а третий - в 0 милях, где я, кроме 8-ми пользователей, должен быть в самом конце.

Я не уверен, что я делаю неправильно в этом.

Кроме того, UserProfile имеет следующую модель

class UserProfile(models.Model): 
    # This field is required. 
    user = models.OneToOneField(User) 
    # Other fields here 
    current_location = models.PointField(null = True) 
    seller_current_location = models.PointField(null = True) 
    objects = models.GeoManager() 
    def __unicode__(self): 
     return u'%s' % (self.user.get_full_name()) 
+1

Имеет ли 'UserProfile' географические поля, отличные от' current_location'? Если это так, 'distance()' может использовать другое поле, чем вы ожидаете. См. [Docs] (https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoquerysets/#geoqueryset-methods) в аргументе 'field_name' значение' distance() '. –

+0

Кроме того, если вы хотите «ближе всего», вы должны заказывать «расстояние». (Хотя это не объяснило бы неупорядоченные результаты, о которых вы сообщаете.) –

+0

@KevinHenry да, у него есть два PointFields pleace, посмотрите на обновление, следует ли указывать имена полей для обоих? – Jonathan

ответ

2

Так как ваш UserProfile содержит более одного географического поля, следует указать тот, который вы хотите с field_name аргумента distance().

UserProfile.objects.exclude(user=user).filter(current_location__distance_lte=(origin, D(mi=distance_mi))).distance(origin, field_name='current_location').order_by('distance')[:20] 

Для получения более подробной информации см. documentation.