You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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)
      }
    }
  }
}

关键修正说明

  1. 视图修正:原CompanySearchView错误继承了HaystackSerializer,改为使用DRF-Haystack提供的HaystackViewSet,它已封装了搜索请求处理、序列化等逻辑;也可以自定义APIView实现更灵活的搜索逻辑。
  2. 路由配置:使用DefaultRouter注册搜索视图,生成标准的RESTful API端点。
  3. 权限控制:根据业务需求设置permission_classes,比如允许匿名访问或仅登录用户访问。
  4. 前端调用:通过GET请求传递q参数,若需要身份验证则在请求头中携带JWT Token。

内容的提问来源于stack exchange,提问作者Corveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:56:08