Haystack可以通过GeoDjango的PointField进行过滤吗?

2 投票
1 回答
800 浏览
提问于 2025-04-17 01:54

我想用django-haystack来对一个模型进行全文搜索。这个模型使用了一个叫PointField的字段来存储坐标。我想根据某个点的距离来过滤搜索结果。请问用Haystack可以做到这一点吗?有没有更好的方法?

from django.contrib.gis.db import models


class Listing(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    location = models.PointField()

1 个回答

3

听起来你想让用户输入一些地理信息,比如地址或者邮政编码,来进行文本搜索。我是这样做的,不过我还不确定这个方法能不能扩展。我刚刚在5分钟前完成了这个。

你应该创建一个自定义的搜索表单,可以从SearchForm或者其他选项中继承(对我来说是FacetedSearchForm)。然后重写搜索方法。

首先,把搜索字符串转换成一个点。你可以参考这个链接

class MainSearchForm(FacetedSearchForm):

    def search(self):

        query = self.cleaned_data['q']
        g = geocoders.Google()
        place, (lat, lng) = g.geocode('%s' % query)
        pnt = fromstr('POINT(%s %s)' % (lng, lat), srid=4326)

接下来,处理搜索查询集,我使用了RelatedSearchQuerySet,因为它允许你使用load_all_queryset(),我就是通过这个来按距离过滤的。GeoDjango在这里派上用场了,使用GeoDjango的距离查询。通过距离查询,你可以选择如何过滤,比如小于、大于某个距离等等。而且你可以选择你想要的任何单位来表示距离。

        sqs = RelatedSearchQuerySet().load_all()
        sqs = sqs.load_all_queryset(Listing, 
                                    Listing.objects.filter(location__distance_lte=(pnt, D(mi=20))))
        return sqs

这应该是一个不错的开始。希望这能给你指明方向。

撰写回答