Jvn
Jvn

Reputation: 495

Django REST Framework: COUNT query generated by PageNumberPagination is slow

I don't want to run count queries on views where count is not needed. How can I turn it off?

I found the following workaround in another post on stackoverflow. The count query is not fired, but I can see pages that have no data. (I can see up to ?page=10000, even though there are only about 10 pages.)

#settings.py
REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 20,
    ...
}
import sys

from django.core.paginator import Paginator
from django.utils.functional import cached_property
from rest_framework.pagination import PageNumberPagination

class CustomPaginatorClass(Paginator):
    @cached_property
    def count(self):
        return sys.maxsize

class CustomPagination(PageNumberPagination):
    django_paginator_class = CustomPaginatorClass

Upvotes: 1

Views: 877

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477437

You can raise a HTTP 404 in case the page does not contain any elements with:

from rest_framework.exceptions import NotFound

class CustomPagination(PageNumberPagination):
    django_paginator_class = CustomPaginatorClass
    
    def paginate_queryset(self, queryset, request, view=None):
        data = super().paginate_queryset(queryset, request, view=view)
        if not data:
            raise NotFound('No data found for this page')
        return data

This will fetch the paginated data with one query, and then we check if there is at least one element. If that is not the case, we know that the page we are using should not exist.

Upvotes: 1

Related Questions