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

DRF过滤与搜索功能失效,始终返回全部数据如何解决?

问题描述

我正在开发一个自助项目——库存管理应用,尝试在DRF中实现过滤与搜索功能。以下是我的实现代码:

views.py

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters    

class ListInventories(generics.ListAPIView):

    serializer_class = Inventory
    filter_backends = [filters.SearchFilter]
    search_fields = ['name']
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['name', 'stock']

    def get(self, request):

        inventories = Inventory.objects.all()
        serializer = InventorySerializers(inventories, many=True)
        return Response({'inventories': serializer.data})


class InventoryDetails(APIView):
    def get(self, request, pk):
        inventories = Inventory.objects.get(id=pk)
        serializer = InventorySerializers(inventories)
        return Response({'inventory': serializer.data})

settings.py配置

INSTALLED_APPS = [
    ...
    'django_filters',
    ...
]
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}

我尝试访问URL:http://127.0.0.1:8000/api/inventory?name=para,以及使用?search=para、?search=anynonsense参数,但DRF始终返回全部数据(目前仅3条数据)。我期望过滤与搜索功能能正常工作,请问该如何解决?


解决方案

你的代码存在三个关键问题,导致过滤和搜索功能失效:

  1. 重写get方法绕过了ListAPIView的内置过滤逻辑
    ListAPIView本身会自动处理filter_backends定义的过滤/搜索逻辑,但你自定义了get方法,直接查询所有Inventory数据,完全跳过了DRF的过滤流程。

  2. filter_backends被重复赋值覆盖
    你先设置了filter_backends = [filters.SearchFilter],随后又重新赋值为[DjangoFilterBackend],导致SearchFilter被覆盖,搜索功能无法生效。

  3. serializer_class配置错误
    serializer_class应该指定序列化器类InventorySerializers,而不是模型类Inventory。

修正后的views.py代码

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters, generics
from rest_framework.response import Response

class ListInventories(generics.ListAPIView):
    # 修正序列化器类
    serializer_class = InventorySerializers
    # 合并两个过滤后端,避免覆盖
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ['name', 'stock']
    search_fields = ['name']
    # 移除自定义get方法,使用ListAPIView默认实现
    queryset = Inventory.objects.all()


class InventoryDetails(APIView):
    def get(self, request, pk):
        inventories = Inventory.objects.get(id=pk)
        serializer = InventorySerializers(inventories)
        return Response({'inventory': serializer.data})

补充说明

  • 移除自定义get方法后,ListAPIView会自动基于queryset属性,通过filter_backends对查询集完成过滤/搜索处理。
  • 现在可正常使用以下参数:
    • 过滤:http://127.0.0.1:8000/api/inventory?name=para 或 ?stock=100
    • 搜索:http://127.0.0.1:8000/api/inventory?search=para

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:31:00