Django模型为模型结果中的每个元素添加距离值

时间:2016-05-20 04:35:51

标签: python django

使用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)中函数返回的每个项目的计算距离?

2 个答案:

答案 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