Django REST Framework `pagination_class` on ViewSet is ignored

Describe the Problem

I have a ModelViewSet in Django REST Framework designed to return a list of Order objects. To improve performance, I'm trying to implement custom pagination that limits the results to 65 per page.

Despite setting the pagination_class property directly on my ViewSet, the API endpoint continues to return the full, unpaginated queryset (over 300 objects). It seems my custom pagination class is being completely ignored.

My goal is for the API to return a paginated response with a count, next, previous, and a results list containing a maximum of 65 items when I request .../api/orders/?page=1.

What I Tried

Here is my setup:

1. pagination.py: I created a custom pagination class.

# my_app/pagination.py
from rest_framework.pagination import PageNumberPagination

class CustomOrderPagination(PageNumberPagination):
    page_size = 65
    page_size_query_param = 'page_size'
    max_page_size = 100

2. views.py: I assigned this custom class to my ViewSet. The queryset uses select_related and prefetch_related for performance.

# my_app/views.py
from rest_framework import viewsets
from django.db.models import Sum
from .models import Order
from .serializers import OrderSlimSerializer
from .pagination import CustomOrderPagination

class OrderViewSet(viewsets.ModelViewSet):
    # I explicitly set the pagination class here
    pagination_class = CustomOrderPagination

    serializer_class = OrderSlimSerializer
    queryset = Order.objects.select_related('client').prefetch_related(
        'orderitem_set__location__service_plan'
    ).annotate(
        total_amount=Sum('orderitem_set__service_plan__service_fee')
    )
    # ... (permission_classes, filter_backends, etc.) ...

3. serializers.py: I'm using optimized "slim" serializers to keep the payload small.

# my_app/serializers.py
class LocationItemSerializer(serializers.ModelSerializer):
    # ... returns a small payload for each location ...
    class Meta:
        model = OrderItem
        fields = ['location_name', 'service_plan_details']

class OrderSlimSerializer(serializers.ModelSerializer):
    client_name = serializers.CharField(source='client.name')
    locations = LocationItemSerializer(source='orderitem_set', many=True)
    charge_amount = serializers.DecimalField(source='total_amount', read_only=True)

    class Meta:
        model = Order
        fields = ['id', 'order_number', 'client_name', 'locations', 'charge_amount']

4. The Request: I am making the request correctly with the page parameter.

curl "http://localhost:8000/api/orders/?page=1"

5. Pagination is Configured in Settings.py:

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 100,
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.BasicAuthentication",
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.TokenAuthentication",
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ],
}

The Result: The response is a single list of all 300+ Order objects, not a paginated dictionary like {"count": 368, "next": ..., "results": [...]}.

Question: Why is my pagination_class setting being ignored on the OrderViewSet, and what is the correct way to ensure this custom pagination is applied? Is there a global setting I might be missing that disables pagination entirely?

PS: I also checked out this question, but since it’s about plain ViewSet, not ModelViewSet, I wasn’t sure how to adapt it to my case.

Thanks for the replies!

Turns out the issue was on my side — I had defined CustomOrderPagination in a separate pagination.py file but was importing it from a different module that wasn’t actually being used by the ViewSet.

To debug, I added:

def paginate_queryset(self, queryset):
    print("called paginate_queryset")
    return super().paginate_queryset(queryset)

But nothing was printed — and that’s when I realized I was assigning a pagination class that wasn't even getting loaded. Once I fixed the import and confirmed the correct pagination class was being used, everything started working as expected.

Appreciate your help — especially the suggestion to override paginate_queryset(), that helped me track it down 🙌


One of those “it works in one tab, but not in the one you’re testing” moments 😅 Thanks again!

Вернуться на верх