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条数据)。我期望过滤与搜索功能能正常工作,请问该如何解决?
解决方案
你的代码存在三个关键问题,导致过滤和搜索功能失效:
重写
get方法绕过了ListAPIView的内置过滤逻辑
ListAPIView本身会自动处理filter_backends定义的过滤/搜索逻辑,但你自定义了get方法,直接查询所有Inventory数据,完全跳过了DRF的过滤流程。filter_backends被重复赋值覆盖
你先设置了filter_backends = [filters.SearchFilter],随后又重新赋值为[DjangoFilterBackend],导致SearchFilter被覆盖,搜索功能无法生效。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
相关产品推荐
相关产品推荐

