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

Django中Datatables服务端自定义分页数据返回异常问题排查

解决Datatables服务端自定义分页数量不生效的问题

Hey there, let's dig into why your Datatables isn't pulling 50 records per page like you configured—this is a common gotcha with server-side processing!

问题根源

The core issue here is that you're manually handling pagination with Django's Paginator and a URL page parameter, but Datatables uses its own set of query parameters for server-side pagination: start (the index of the first record to fetch) and length (the number of records per page). Your custom pagination logic isn't hooked into these parameters, and the BaseDatatableView you're using already has built-in pagination that defaults to 10 records—so it's overriding your 50-item setting.

Plus, Datatables never sends a page parameter in its AJAX requests, so your URL's (?P<page>\d+) capture is irrelevant here, and your manual pagination code isn't actually doing what you think it is.

修正方案

Let's fix this by leaning into BaseDatatableView's built-in capabilities instead of reinventing the wheel:

1. 更新视图类

Remove your custom pagination logic—BaseDatatableView handles pagination, sorting, and filtering automatically if you configure it correctly. Just set the page_length attribute to your desired default per-page count, and return your base queryset from get_initial_queryset:

from django.db.models import Q
from django.contrib.auth.mixins import LoginRequiredMixin
from datatables.views import BaseDatatableView
from .models import ProductSerialNumbers

class ProductSerialNumbersListJSon(LoginRequiredMixin, BaseDatatableView):
    model = ProductSerialNumbers
    columns = ['snumber', 'order', 'product', 'registration_date']
    order_columns = ['snumber', 'order', 'product', 'registration_date']
    # Set default records per page here
    page_length = 50

    def get_initial_queryset(self):
        # Return your base filter queryset—let BaseDatatableView handle pagination
        return ProductSerialNumbers.objects.filter(
            Q(snumber__isnull=True) | Q(order_id__isnull=True) | Q(order_id__finished=0)
        ).order_by("id")

2. 修正URL配置

Drop the page parameter from your URL—Datatables won't use it, and BaseDatatableView expects a standard endpoint without pagination segments:

from django.urls import path
from . import views

urlpatterns = [
    # ... other URLs
    path('warehouse_tabledata/', views.ProductSerialNumbersListJSon.as_view(), name='warehouse_list_json'),
]

3. 前端Datatables配置(重要!)

Make sure your front-end Datatables initialization enables server-side processing and aligns with your backend settings. Here's a sample config:

$(document).ready(function() {
    $('#your-product-table').DataTable({
        serverSide: true,
        ajax: "{% url 'warehouse_list_json' %}", // Use your URL name
        pageLength: 50, // Match your backend's default page_length
        // Optional: Let users choose per-page counts
        lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
        columns: [
            { data: 'snumber' },
            { data: 'order' },
            { data: 'product' },
            { data: 'registration_date' }
        ]
    });
});

为什么这能解决问题?

  • BaseDatatableView automatically reads the length parameter sent by Datatables (which will be 50 if you set pageLength in the front-end, or your backend's page_length default).
  • It handles the offset calculation using the start parameter, so you don't have to manually manage page numbers and offsets.
  • Your queryset is filtered once, and the view takes care of slicing it to the correct page size for each request.

验证返回的JSON

After making these changes, your JSON response should have:

  • recordsTotal: Total number of unfiltered records in your queryset
  • recordsFiltered: Total number of records after any search/filtering (same as recordsTotal if no filters are applied)
  • data: Exactly 50 records (or the user-selected count) per request

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:55:19