この 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() メソッド呼び出しとして実行したくありません (データベース内の潜在的な場所ごとに 1 つのクエリに対して 1 つのクエリ)。いくつかの質問:
- リストを距離順に並べ替えるにはどうすればよいですか? モデルで定義したネイティブソートを外して「order_by()」を使用しても、別のもの (id だと思います) でソートしています。
- 私はパフォーマンスの問題について間違っていますか? Django はクエリを最適化するので、代わりに extra() を使用する必要がありますか?
- これは完全に間違った方法ですか? putz のように手動でロールするのではなく、geo ライブラリを使用する必要がありますか?