按距离对结果进行排序,并获取它们与查询点之间的距离

时间:2017-09-07 23:54:13

标签: python django geodjango

我目前按照我的模型的距离对结果进行排序:

views.py

    SearchPoint = Point(long, lat)    
    res = Model.objects.filter(location__distance_lte=(SearchPoint, D(m=2000)))
               .annotate(distance=Distance('location', SearchPoint))
               .order_by('distance')

这允许我按distance对{2000}范围内的结果进行排序。

现在我想显示SearchPoint给出的搜索者与Model的结果之间的距离。

Models.py 在我的模型类中,我定义了以下属性:

@property
def distance_to_searcher(self):
    distance =self.location.distance(SearchPoint)
    return distance * 100

但是我收到以下错误:

  

名称'SearchPoint'未定义

我知道这没有定义,因为它在views.py文件中定义,这是一个GET请求,并从URL获取long和lat参数并将它们放入Point()类。

理想情况下,我会将距离调整到一个不错的数字。

编辑:我在 views.py

中定义SearchPoint
def get_context_data(self, **kwargs):
    if self.request.method == 'GET':
        form = LocationForm(self.request.GET)
        if form.is_valid():
            SearchPoint=Point(form.cleaned_data['Lng'],form.cleaned_data['Lat'])
        else:
            form = LocationForm()
            SearchPoint=Point(0,0)

2 个答案:

答案 0 :(得分:1)

我发现解决方案只是在我的模板中调用.distanceres变量已将距离作为属性,无需其他属性。

答案 1 :(得分:1)

由于您正在创建此查询:

res = Model.objects.filter(location__distance_lte=(SearchPoint, D(m=2000)))
                   .annotate(distance=Distance('location', SearchPoint))
                   .order_by('distance')

使用annotate,您正在向查询返回的每个模型对象“添加”一个名为distance的字段。

那说,如果你这样做:

for item in res:
    print(item.distance)

您将获得每个模型对象与SearchPoint的距离。

如果您绝对想在模型中使用@property,则应以接受SearchPoint作为参数的方式对其进行定义:

@property
def distance_to_searcher(self, search_point):
    distance=self.location.distance(search_point)
    return distance * 100

但您也必须修改您的查询:

res = Model.objects.filter(location__distance_lte=(SearchPoint, D(m=2000)))
                   .order_by('distance')

因为您不再需要使用注释在查询集中创建distance字段 现在,如果你这样做:

for item in res:
    print(item.distance_to_searcher(SearchPoint))

您将获得与上述相同的结果。