如何将VueJS搜索请求与Django Haystack的search_query_set API集成?
实现Django-Haystack搜索API与VueJS对接
我正在尝试为ArboristCompany配置自定义search_query_set,基于Django-Haystack和DRF-Haystack开发。目前文档里都是结合模板的实现方式,但我已有VueJS搜索页面,需要像登录/注册API那样,把Vue的搜索请求和后端搜索API端点集成起来。
现有代码文件
serializers.py
class CompanySerializer(HaystackSerializer): class Meta: index_class = [ArboristCompanyIndex] fields = [ 'text', 'company_name', 'company_city', 'company_state' ]
search_indexes.py
class ArboristCompanyIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.EdgeNgramField(document=True, use_template=True) company_name = indexes.CharField(model_attr='company_name') company_city = indexes.CharField(model_attr='company_city') company_state = indexes.CharField(model_attr='company_state') # 不直接索引company_price,使用自定义的price_display方法 company_price_display = indexes.CharField(model_attr='price_display', null=True) experience = indexes.CharField(model_attr='experience') def get_model(self): return ArboristCompany def index_queryset(self, using=None): return self.get_model().objects.filter(content='foo').order_by('company_name', 'company_city', 'company_state', 'experience')
views.py
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework_simplejwt.authentication import JWTAuthentication from django.contrib.auth import login from rest_framework_simplejwt.tokens import RefreshToken from .serializers import LoginSerializers, RegisterSerializer, CompanySerializer from haystack.query import SearchQuerySet from rest_framework.permissions import AllowAny from drf_haystack.viewsets import HaystackViewSet @authentication_classes([JWTAuthentication]) class LoginView(APIView): def post(self, request, *args, **kwargs): serializer = LoginSerializers(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] login(request, user) # 生成JWT Token refresh = RefreshToken.for_user(user) access_token = str(refresh.access_token) return Response({ 'message': '登录成功', 'access_token': access_token, 'refresh_token': str(refresh), }, status=status.HTTP_200_OK) # 注:原代码中return后还有if判断,逻辑不可达,已修正 class RegisterView(APIView): def post(self, request): serializer = RegisterSerializer(data=request.data, context={'request': request}) if serializer.is_valid(): serializer.save() return Response({ 'message': '注册成功', }, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 修正搜索视图:使用DRF-Haystack的HaystackViewSet,自动处理搜索逻辑 class CompanySearchViewSet(HaystackViewSet): index_models = [ArboristCompany] serializer_class = CompanySerializer permission_classes = [AllowAny] # 根据需求设置权限,比如登录用户才能访问 # 或者自定义APIView实现(如果需要更灵活的逻辑) # class CompanySearchView(APIView): # permission_classes = [AllowAny] # def get(self, request): # query = request.GET.get('q', '') # if not query: # return Response({'error': '缺少搜索关键词'}, status=status.HTTP_400_BAD_REQUEST) # # 执行搜索:根据text字段匹配,或者指定字段搜索 # queryset = SearchQuerySet().filter(text__contains=query).order_by('company_name', 'company_city', 'company_state', 'experience') # serializer = CompanySerializer(queryset, many=True) # return Response(serializer.data, status=status.HTTP_200_OK)
urls.py(应用)
from django.urls import path, include from arborfindr.views import index from .views import homeowner_info, review_info, services_info, update_password, homeowner_dashboard, company_profile, edit_homeowner_dashboard, edit_company_profile, arbor_review from django.contrib.auth import views as auth_views from django.conf import settings from django.conf.urls.static import static from .views import RegisterView, LoginView, CompanySearchViewSet from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView from rest_framework import routers app_name = 'arborfindr' router = routers.DefaultRouter() router.register(r'company/search', CompanySearchViewSet, basename='company-search') urlpatterns = [ path('register/', RegisterView.as_view(), name='register'), path('login/', LoginView.as_view(), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), path('update_password/', update_password, name='update_password'), path('homeowner_dashboard/', homeowner_dashboard, name='homeowner_dashboard'), path('company_profile/', company_profile, name='company_profile'), path('edit_homeowner_dashboard/', edit_homeowner_dashboard, name='edit_homeowner_dashboard'), path('edit_company_profile/', edit_company_profile, name='edit_company_profile'), path('arbor/review/', arbor_review, name='arbor_review'), path('homeowner/', homeowner_info), path('review_arbor/', review_info), path('services/', services_info), path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('arborfindr/', index), # 添加搜索API路由 path('', include(router.urls)), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
VueJS前端对接示例
在Vue组件中发送搜索请求(使用axios为例):
import axios from 'axios' export default { data() { return { searchQuery: '', companies: [] } }, methods: { async searchCompanies() { try { const response = await axios.get('/api/arborfindr/company/search/', { params: { q: this.searchQuery }, // 如果需要登录验证,带上token headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }) this.companies = response.data } catch (error) { console.error('搜索失败:', error) } } } }
关键修正说明
- 视图修正:原
CompanySearchView错误继承了HaystackSerializer,改为使用DRF-Haystack提供的HaystackViewSet,它已封装了搜索请求处理、序列化等逻辑;也可以自定义APIView实现更灵活的搜索逻辑。 - 路由配置:使用
DefaultRouter注册搜索视图,生成标准的RESTful API端点。 - 权限控制:根据业务需求设置
permission_classes,比如允许匿名访问或仅登录用户访问。 - 前端调用:通过GET请求传递
q参数,若需要身份验证则在请求头中携带JWT Token。
内容的提问来源于stack exchange,提问作者Corveloper
相关产品推荐
相关产品推荐

