之前配置过elasticsearch,订制返回值的时候,我们需要修改的不多。
需要注意的是,项目的需求是在key-search的同时支持模糊搜索。
一、封装elasticsearch查询结果
from django.http import JsonResponse
from drf_haystack.viewsets import HaystackViewSet
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
class ElasticSearchReturn(HaystackViewSet):
"""封装elasticsearch查询结果"""
def get_queryset(self, index_models=[]):
if self.queryset is not None and isinstance(self.queryset, self.object_class):
queryset = self.queryset.all()
else:
queryset = self.object_class()._clone()
if len(index_models):
queryset = queryset.models(*index_models)
elif len(self.index_models):
queryset = queryset.models(*self.index_models)
return queryset
def list(self, request, *args, **kwargs):
"""重写list查询方法,封装数据格式,使用Django自带的分页器"""
limit = int(request.GET.get('limit', "20"))
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page, many=True)
paginator = Paginator(serializer.data, limit)
try:
page_item = paginator.page(page)
except PageNotAnInteger:
page_item = paginator.page(1)
except EmptyPage:
page_item = paginator.page(paginator.num_pages)
return JsonResponse({
"code": 0,
"msg": "OK",
"count": len(queryset),
"data": [item for item in page_item]
})
二、重写SearchView中的方法
class ProviderSearchView(SearchView):
def get_context_data(self, *args, **kwargs):
context = super(ProviderSearchView, self).get_context_data(*args, **kwargs)
print(self.queryset)
for i in context['object_list']:
print(i.author)
return context
def get_queryset(self):
# haystack自己的queryset, 这里是所有数据
# queryset = super(ProviderSearchView, self).get_queryset()
# 使用字段查询返回的queryset
queryset = ElasticSearchReturn().get_queryset()
return queryset.filter(is_active=True)
def get(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
print(form)
return self.form_valid(form)
三、 修改URL
from .views import *
router.register(r'^es_search', SearchViewSet, basename='search')
urlpatterns += router.urls
参考:
在django项目中加入全文检索(使用haystack)并返回json形式的数据
评论区