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

Django REST API中GET请求分页功能失效问题求助

问题分析与解决方案

核心问题拆解

  1. APIView 分页失效:LogsNewAPI 继承自 APIView,但 APIView 不会自动应用 pagination_class,且你先将完整QuerySet转为DataFrame,导致分页逻辑完全失效(相当于先取全量数据再处理,失去分页意义)。
  2. ListView 用错场景:LogsAPI 继承自 ListView,这是Django用于渲染HTML模板的视图类,要求get_queryset必须返回QuerySet,但你返回了HttpResponse,因此触发报错。ListView不适合开发JSON接口。

解决方案一:基于 APIView 手动实现分页

修改 LogsNewAPI,先对QuerySet分页,再处理数据并返回带分页元信息的响应:

from rest_framework.response import Response

class LogsNewAPI(APIView):
    pagination_class = CustomPagination

    def get(self, request, *args, **kwargs):
        envid = self.kwargs.get('envid')
        nodeid = self.kwargs.get('nodeid')
        startdatetime = self.request.GET.get('startdatetime')
        enddatetime = self.request.GET.get('enddatetime')

        # 1. 先获取过滤后的QuerySet(不要立即转DataFrame)
        queryset = PegaAlerts.objects.filter(
            envId=envid, 
            serverId=nodeid, 
            generateddatetime__lte=enddatetime, 
            generateddatetime__gte=startdatetime
        ).order_by('generateddatetime')

        # 2. 实例化分页类,对QuerySet执行分页
        paginator = self.pagination_class()
        paginated_data = paginator.paginate_queryset(queryset, request)

        # 3. 对分页后的结果做DataFrame清洗处理
        df = read_frame(paginated_data)
        processed_data = df[['generateddatetime','msgid','fullLine']].to_dict('records')

        # 4. 返回带分页元信息的标准API响应(包含count/next/previous字段)
        return paginator.get_paginated_response(processed_data)

解决方案二:基于 ListAPIView 自动实现分页

使用DRF的ListAPIView(专为列表接口设计,内置分页逻辑),重写list方法加入DataFrame处理:

from rest_framework import generics

class LogsAPI(generics.ListAPIView):
    pagination_class = CustomPagination

    def get_queryset(self):
        envid = self.kwargs.get('envid')
        nodeid = self.kwargs.get('nodeid')
        startdatetime = self.request.GET.get('startdatetime')
        enddatetime = self.request.GET.get('enddatetime')
        
        # 返回过滤后的QuerySet(符合ListView/ListAPIView的要求)
        return PegaAlerts.objects.filter(
            envId=envid, 
            serverId=nodeid, 
            generateddatetime__lte=enddatetime, 
            generateddatetime__gte=startdatetime
        ).order_by('generateddatetime')

    def list(self, request, *args, **kwargs):
        # 调用内置逻辑获取分页后的QuerySet
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)

        if page is not None:
            # 分页场景下处理数据
            df = read_frame(page)
            processed_data = df[['generateddatetime','msgid','fullLine']].to_dict('records')
            return self.get_paginated_response(processed_data)
        
        # 无分页场景下返回全量处理后的数据
        df = read_frame(queryset)
        processed_data = df[['generateddatetime','msgid','fullLine']].to_dict('records')
        return Response(processed_data)

关键注意事项

  • 分页逻辑必须先作用于QuerySet,再进行DataFrame处理,否则会加载全量数据,违背分页的初衷。
  • 开发JSON接口时,优先使用DRF提供的视图类(APIView/ListAPIView等),不要用Django原生的ListView(用于模板渲染)。
  • 你的CustomPagination配置与请求参数(page_size/page_number)匹配,无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:50:29