如何在 DRF 中搜索多个内容(全文、地理位置等)?
Posted
技术标签:
【中文标题】如何在 DRF 中搜索多个内容(全文、地理位置等)?【英文标题】:How can I do search for multiple things (full-text, geolocation etc) in DRF? 【发布时间】:2019-12-24 01:55:27 【问题描述】:我在 Django-REST 中有一个模型,它有名称、描述等,以及使用 GeoDjango 的地理定位。现在,我想进行复杂的搜索,在名称和描述字段中进行全文搜索以及地理位置搜索(用户给出位置点和最大距离)。如果需要,我希望它们能够独立工作并一起工作。
我已经了解了如何进行全文搜索(此处:https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/search/)以及如何根据距离进行搜索(此处:https://docs.djangoproject.com/en/2.2/ref/contrib/gis/db-api/)。
到目前为止我的代码(型号,无所谓,只要想名字,描述和位置点):
class SearchAuctions(APIView):
permission_classes = [AllowAny]
def get(self, request, format=None):
"""
Return auctions after filtering.
"""
items = AuctionItem.objects
if 'textToSearch' in request.data.keys():
textToSearch = request.data['textToSearch']
items = AuctionItem.objects.annotate(
search=SearchVector('name', 'description'),
).filter(search=textToSearch)
itemSerializer = AuctionItemSerializer(items, many=True)
return Response(itemSerializer.data)
不确定如何在过滤器之间创建链接。我虽然提出了多个请求并找到了共同的元素,但我猜这太慢了。
【问题讨论】:
您可以应用多个过滤器,例如AuctionItem.objects.filter(search=textToSearch).filter(location=locationToSearch)
这是个好主意,但是如果我不希望某个过滤器发生怎么办?你看到了,我可能有 5 个过滤器,它们可能会发生也可能不会发生。
查询仅在访问时进行评估。因此,您可以从基本查询 items = AuctionItem.objects
开始,然后有条件地向其添加过滤器。例如if searchText: items = items.filter(search=textToSearch)
和if searchLoc: items = items.filter(...)
,一旦应用了所有内容,就将其交给序列化程序。
嗯,我知道,只是全文搜索需要注释部分。现在我发现我一开始就可以做到,如果全文搜索不发生也没关系,所以一切都很好。
谢谢,如果您愿意,请为加分写一个正确的答案。
【参考方案1】:
正如我在评论中提到的,您可以将过滤器应用于查询而无需对其进行评估。 这允许您根据条件创建查询,例如
class SearchAuctions(APIView):
permission_classes = [AllowAny]
def get(self, request, format=None):
"""
Return auctions after filtering.
"""
items = AuctionItem.objects
if 'textToSearch' in request.data.keys():
textToSearch = request.data['textToSearch']
items = items.annotate(
search=SearchVector('name', 'description'),
).filter(search=textToSearch)
if 'locationToSearch' in request.data.keys():
locationToSearch = request.data['locationToSearch']
items = items.filter(location=locationToSearch)
itemSerializer = AuctionItemSerializer(items, many=True)
return Response(itemSerializer.data)
【讨论】:
以上是关于如何在 DRF 中搜索多个内容(全文、地理位置等)?的主要内容,如果未能解决你的问题,请参考以下文章