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

Datatables.net结合DRF实现服务端处理时分页无法正常跳转问题

问题核心原因

Datatables服务端模式默认发送start(当前页偏移量)、length(每页条数)格式的分页参数,同时携带大量列、排序、搜索类冗余参数,而DRF默认分页器仅识别page(页码)、page_size(每页条数)格式的参数,参数格式不匹配导致DRF无法正确解析分页请求,永远返回第一页数据。


完整解决方案

前端配置优化

保留你已有的响应映射逻辑,新增请求参数转换逻辑,过滤冗余参数、适配DRF的参数格式即可,示例配置如下:

$('#你的表格ID').DataTable({
  serverSide: true,
  processing: true, // 加载中提示,可选
  ajax: {
    url: "你的DRF接口地址",
    type: "GET",
    // 自定义请求参数,适配DRF格式
    data: function (d) {
      // 删掉Datatables默认的冗余列参数,不需要搜索/排序功能可直接清空
      delete d.columns;
      delete d.order;
      delete d.search;
      // 转换为DRF默认分页器识别的参数
      d.page_size = d.length;
      d.page = (d.start / d.length) + 1;
      // 若需要保留搜索/排序功能,放开下方注释做参数转换即可
      // if(d.order.length) d.ordering = `${d.order[0].dir === 'desc' ? '-' : ''}${d.columns[d.order[0].column].data}`
      // if(d.search.value) d.search = d.search.value
      return d;
    },
    // 你原有响应映射逻辑保留
    dataFilter: function (res) {
      res = JSON.parse(res);
      return JSON.stringify({
        recordsTotal: res.count,
        recordsFiltered: res.count,
        data: res.results
      })
    }
  },
  // 其余你的列配置、样式配置保留即可
  columns: [
    // 你的列定义
  ]
})

后端DRF配置适配

方案1:使用默认分页器(推荐)

直接复用DRF自带的PageNumberPagination,配置对应参数名即可:

from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet
from .models import 你的业务模型
from .serializers import 你的业务序列化器

# 自定义分页规则
class CustomPagination(PageNumberPagination):
    page_size_query_param = 'page_size' # 匹配前端传的page_size参数
    max_page_size = 100 # 限制最大每页条数,防止恶意请求

# 你的业务视图
class YourBusinessViewSet(ModelViewSet):
    queryset = 你的业务模型.objects.all()
    serializer_class = 你的业务序列化器
    pagination_class = CustomPagination
    # 若需要支持搜索、排序功能,放开下方配置即可
    # filter_backends = [SearchFilter, OrderingFilter]
    # search_fields = ['字段1', '字段2'] # 允许搜索的字段
    # ordering_fields = ['字段1', '字段2'] # 允许排序的字段

方案2:自定义Datatables专用分页器

如果你不想修改前端参数,要直接解析Datatables原生的start、length参数,可以自定义分页器:

from rest_framework.pagination import BasePagination
from rest_framework.response import Response

class DatatablesPagination(BasePagination):
    def paginate_queryset(self, queryset, request, view=None):
        self.start = int(request.query_params.get('start', 0))
        self.length = int(request.query_params.get('length', 10))
        self.total = queryset.count()
        return list(queryset[self.start:self.start+self.length])

    def get_paginated_response(self, data):
        return Response({
            'count': self.total,
            'next': None,
            'previous': None,
            'results': data
        })

在视图中把pagination_class替换为DatatablesPagination即可使用。


验证排查点
  • 点击分页按钮时打开浏览器控制台Network面板,确认请求参数中的page/page_size值随页码切换正常变化
  • 确认DRF返回的count字段为总数据条数,results长度和page_size一致
  • 若出现分页页码显示错误,检查前端dataFilter中recordsTotal和recordsFiltered是否都赋值为接口返回的count,两个值不一致会导致Datatables分页计算异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:06:00