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

如何在Django REST Framework的APIView中使用get_queryset及过滤分页功能

问题解决方案

核心问题解答

1. 能否直接在APIView中使用get_queryset?

可以但完全不推荐。APIView是DRF最底层的基础视图类,本身没有内置get_queryset、过滤、分页的相关处理逻辑,要手动实现的话需要自行编写过滤触发、分页响应格式化的全部代码,相当于重复造通用视图的轮子,代码冗余且容易出错。

2. APIView中能否同时配置filterset_class和分页功能?

可以但仍需要自行实现调用逻辑:你需要手动实例化filterset类处理查询集,手动调用分页类对结果做切片、生成标准化分页响应格式,本质是把DRF通用视图已经封装好的逻辑再重写一遍,没有实际价值。

3. 最优实现方案

使用GenericViewSet + 对应Mixin的组合,即可把所有CRUD操作、过滤分页能力全部整合到同一个视图类中,无需拆分接口,也无需重复编写基础逻辑。

具体实现代码

视图类代码

from rest_framework import viewsets, mixins, status
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
import django_filters.rest_framework
# 导入你项目中已有的模块
from .models import Lead
from .serializers import LeadSerializer
from .filters import LeadsFilter
from .pagination import CustomPagination


class LeadsViewSet(mixins.ListModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.CreateModelMixin,
                   mixins.DestroyModelMixin,
                   viewsets.GenericViewSet):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    queryset = Lead.objects.all().order_by('-date_created')
    serializer_class = LeadSerializer
    filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = LeadsFilter

    def get_queryset(self):
        # 简化后的自定义过滤逻辑,和原有效果一致
        source = self.request.GET.get("source", None)
        lead_status = self.request.GET.get("lead_status", None)
        queryset = super().get_queryset()
        
        if source:
            source_values = source.split(",")
            queryset = queryset.filter(source__in=source_values)
        if lead_status:
            lead_status_values = lead_status.split(",")
            queryset = queryset.filter(lead_status__in=lead_status_values)
        return queryset

    # 保留你原有批量创建的逻辑
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

路由配置

可以直接使用DRF的Router自动生成路由,替代原有三个路由:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'lead', LeadsViewSet, basename='lead')

urlpatterns = [
    # 你的其他路由
] + router.urls

如果不想用Router,也可以手动配置路由:

path('lead', LeadsViewSet.as_view({'get': 'list', 'post': 'create'}), name='leads-list'),
path('lead/<int:pk>', LeadsViewSet.as_view({'get': 'retrieve', 'delete': 'destroy'}), name='leads-detail'),

方案优势

  • 所有业务逻辑都在同一个视图类中,维护更方便,无需拆分单独的列表查询接口
  • 直接复用DRF内置的过滤、分页、CRUD逻辑,无需手动重复实现,降低BUG率
  • 路由更简洁,完全符合RESTful接口规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:24:02