回复Tom的答案,SQLite默认情况下不起作用,因为SQLite默认情况下缺少数学函数。 没问题,很容易添加:
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
from mysite import settings
cursor = connection.cursor()
if settings.DATABASE_ENGINE == 'sqlite3':
connection.connection.create_function('acos', 1, math.acos)
connection.connection.create_function('cos', 1, math.cos)
connection.connection.create_function('radians', 1, math.radians)
connection.connection.create_function('sin', 1, math.sin)
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 location_location WHERE 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)
http://www.movable-type.co.uk/scripts/latlong.html
并查看相关的维基百科文章。 (b) 我相信你会用变量替换硬编码的用户坐标 :-) (c) 温馨提示读者,你所使用的距离单位有些过时(与罗马军团标准步伐长度的1000倍有关,我相信) :-) - John Machin