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

解决TypeError:SearchProduct.get()收到意外关键字参数'query'问题

解决Django GenericAPIView接收query参数时的TypeError问题

问题核心

调用继承自GenericAPIView的SearchProduct视图时出现错误:TypeError: SearchProduct.get() got an unexpected keyword argument 'query',原因是URL路径中定义的<str:query>参数会被Django自动传递给视图的get方法,但当前get方法未声明接收该参数;同时前后端参数传递方式不统一,导致逻辑混乱。


解决方案(两种可选)

方案1:统一使用URL路径参数传递query

修改视图代码(product_views.py)

from django.db.models import Q
from rest_framework.response import Response
from rest_framework import status

class SearchProduct(GenericAPIView):
    serializer_class = ProductSerializer
    pagination_class = CustomPagination1

    def get_queryset(self, query=None, *args, **kwargs):
        # 优先使用路径传递的query,兼容GET参数方式
        query = query or self.request.GET.get("query")
        if not query:
            # 无搜索词时返回空集合,可根据需求改为返回所有商品
            return Product.objects.none()
        
        lookup = Q(name__icontains=query) | Q(description__icontains=query) | Q(producttag__title__icontains=query)
        return Product.objects.filter(lookup).distinct()

    def get(self, request, query):
        queryset = self.get_queryset(query=query)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            result = self.get_paginated_response(serializer.data)
            data = result.data
        else:
            serializer = self.get_serializer(queryset, many=True)
            data = serializer.data
        
        payload = {
            'return_code': '0000',
            'return_message': 'Success',
            'data': data
        }
        return Response(payload, status=status.HTTP_200_OK)

关键修改点:

  • 给get方法添加query参数,接收URL路径传递的值
  • 修复原代码中else分支queryset未定义的错误
  • 调整返回值为约定的payload结构(原代码错误返回了原始分页/序列化数据)

方案2:统一使用URL查询参数传递query(推荐,符合RESTful规范)

搜索接口更适合用?query=xxx的查询参数方式,避免路径中包含特殊字符导致的解析问题。

修改URL配置(product_urls.py)

path('search_product/', views.SearchProduct.as_view(), name="search_product"),

修改视图代码(product_views.py)

from django.db.models import Q
from rest_framework.response import Response
from rest_framework import status

class SearchProduct(GenericAPIView):
    serializer_class = ProductSerializer
    pagination_class = CustomPagination1

    def get_queryset(self, *args, **kwargs):
        query = self.request.GET.get("query", "")
        if not query:
            return Product.objects.none()
        
        lookup = Q(name__icontains=query) | Q(description__icontains=query) | Q(producttag__title__icontains=query)
        return Product.objects.filter(lookup).distinct()

    def get(self, request):
        queryset = self.get_queryset()
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            result = self.get_paginated_response(serializer.data)
            data = result.data
        else:
            serializer = self.get_serializer(queryset, many=True)
            data = serializer.data
        
        payload = {
            'return_code': '0000',
            'return_message': 'Success',
            'data': data
        }
        return Response(payload, status=status.HTTP_200_OK)

修改前端请求(productAction.js)

用axios的params参数自动处理URL编码:

export const productsSearchAction = (query , pageNumber) => async (dispatch , getState) => {
    try {
        dispatch({type: PRODUCTS_SEARCH_REQUEST});
        const {data} = await axios.get(`http://127.0.0.1:8000/api/v1/products/search_product/`, {
            params: {
                query: query,
                page: pageNumber
            }
        });
        dispatch({type: PRODUCTS_SEARCH_SUCCESS , payload: data});
        localStorage.setItem("productsSearch" , JSON.stringify(data));
    } catch (error) {
        dispatch({
            type: PRODUCTS_SEARCH_FAILED,
            payload: error.response && error.response.data.detail ? error.response.data.detail : error.message,
        });
    }
}

错误点总结

  1. 视图方法未接收路径参数:URL中定义的<str:query>会被Django传递给get方法,方法未声明对应参数会触发TypeError
  2. 变量未定义:原代码else分支中queryset变量未声明,会导致NameError
  3. 返回结构不符:原代码直接返回分页/序列化数据,未按约定返回包含return_code的结构
  4. 参数传递不统一:前端同时用路径和查询参数传递值,后端仅从GET取query,逻辑混乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:53:17