使用Django和Python 3.x,我从一个模型中提取出来自用户位置的给定半径范围内的元素。由于数据库的限制,我无法在Django中使用内置的地理功能。我目前正在使用以下功能:
def nearby(self,lat,lng,radius=20,use_miles=True):
assert isinstance(radius,(float,int))
assert isinstance(use_miles,bool)
distance_unit = 3959 if use_miles else 6371
cursor = connection.cursor()
cursor.execute("SELECT deal_ID,("
"%d*acos(cos(radians(%f))*cos(radians(%f))*"
"cos(radians(lng)-radians(%f))+sin(radians(%f))*"
"sin(radians(lat))))"
"AS distance FROM local_deals HAVING distance < %f "
"ORDER BY distance ASC;" % (distance_unit,lat,lat,lng,radius))
ids = [row[0] for row in cursor.fetchall()]
return LocalDeals.filter(deal_id__in=ids)
我的问题是,如何添加字段&#34;距离&#34;,对应于行return LocalDeals.filter(deal_id__in=ids)
中函数返回的每个项目的计算距离?
答案 0 :(得分:0)
这是对车轮的重新发明。您应该使用Dwithin。它确实需要安装GeoDjango,但它速度快,带来了许多不同的功能,而不仅仅是在一行中轻松完成此查询的功能。您的查询将是
MyModel.objects.filter(location__diwthin(p,D(m=25)).distance().order_by('distance')
这里p是某个兴趣点,D是django.contrib.gis.measure.D
,m = 25表示25米距离。
答案 1 :(得分:0)
您是否尝试过使用Manager.raw()而不是使用控制台?你可以试试这个:
my_query = "SELECT deal_ID AS id,("
"%d*acos(cos(radians(%f))*cos(radians(%f))*"
"cos(radians(lng)-radians(%f))+sin(radians(%f))*"
"sin(radians(lat))))"
"AS distance FROM local_deals HAVING distance < %f "
"ORDER BY distance ASC;" % (distance_unit,lat,lat,lng,radius)
return LocalDeals.objects.raw(my_query)
只要你有id&amp; LocalDeals中的距离字段,这将返回LocalDeals对象。
参考:https://docs.djangoproject.com/en/1.9/topics/db/sql/#performing-raw-queries