Используя логику расстояния из этого сообщения SO , Я возвращаю правильно отфильтрованный набор объектов с помощью этого кода:
class LocationManager(models.Manager):
def nearby_locations(self, latitude, longitude, radius, max_results=100, use_miles=True):
if use_miles:
distance_unit = 3959
else:
distance_unit = 6371
from django.db import connection, transaction
cursor = connection.cursor()
sql = """SELECT id, (%f * acos( cos( radians(%f) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians(%f) ) + sin( radians(%f) ) * sin( radians( latitude ) ) ) )
AS distance FROM locations_location HAVING distance < %d
ORDER BY distance LIMIT 0 , %d;""" % (distance_unit, latitude, longitude, latitude, int(radius), max_results)
cursor.execute(sql)
ids = [row[0] for row in cursor.fetchall()]
return self.filter(id__in=ids)
Проблема в том, что я не могу понять, как сохранить список / запрос, отсортированный по значению расстояния. Я не хочу делать это как вызов метода extra () по соображениям производительности (один запрос против одного запроса для каждого потенциального местоположения в моей базе данных). Пара вопросов:
- Как отсортировать список по расстоянию? Даже если убрать родную сортировку, которую я определил в своей модели, и использовать "order_by ()", она все равно сортируется по другому (я полагаю, id).
- Я ошибаюсь в отношении производительности, и Django оптимизирует запрос, поэтому вместо этого мне следует использовать extra ()?
- Это совершенно неправильный способ сделать это, и я должен использовать географическую библиотеку вместо того, чтобы раскатывать это вручную, как путц?