3

I have pagination enabled by default, which is based on PageNumberPagination; this had sufficed until now as the API was only used by a front-end. Now we try to build automation on top of it, and I’d like to pass the full, unpaginated result set back to the client.

Is there a way to disable pagination for specific requests, e.g. if a request parameter is passed?

GergelyPolonkai
  • 6,230
  • 6
  • 35
  • 69

7 Answers7

3

I used a similer appraoch to accepted answer

class Unpaginatable(PageNumberPagination):
    def paginate_queryset(self, queryset, request, view=None):
        if request.query_params.get('get_all', False) == 'true':
            return None

        return super(BuildListPagination, self).paginate_queryset(queryset, request, view=view)

now if you pass ?get_all=true while making the request, you will get unpaginated response.

Nithin
  • 5,470
  • 37
  • 44
3

If you are using page number pagination style, the below solution may be better.

    def paginate_queryset(self, queryset, request, view=None):
    if 'page' not in request.query_params:
        return None

    return super().paginate_queryset(queryset, request, view)

So you simply send a request without the page query_param.

klement omeri
  • 428
  • 6
  • 7
1

I actually did go with a custom pagination class:

class Unpaginatable(PageNumberPagination):
    def paginate_queryset(self, queryset, request, view=None):
        if getattr(request, 'get_all', False):
            return None

        return super(BuildListPagination, self).paginate_queryset(queryset, request, view=view)

Now I just have to set request.get_all = True in my viewset and I get all the items.

GergelyPolonkai
  • 6,230
  • 6
  • 35
  • 69
1

thnaks to this answer, Else, if you use limit/offset you can use this in Generic List API View class:

def paginate_queryset(self, queryset):
    if 'limit' not in self.request.query_params:
        return None
    return super().paginate_queryset(queryset)

It worked with python 3.9/ Django 4.0, In my case, this method had no argument named request and view, so I fixed it.

this will also won't render paginator json, when the response is not paginated.

Parsa Dany
  • 35
  • 3
0

You can approximate this with a request limit set to an unfeasibly large number, but you need to configure Django first:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}

Then make a ridiculously high limit request:

GET https://api.example.org/accounts/?limit=999999999999

LimitOffsetPagination - django-rest-framework.org

0

Actually DRF docs for this is very unclear, and there is no clear answer address this issue. After reading the source code, the followling code works for me.

from rest_framework.pagination import LimitOffsetPagination


class Unpaginated(LimitOffsetPagination):
    def paginate_queryset(self, queryset, request, view=None):
        self.count = self.get_count(queryset)
        self.limit = self.get_limit(request)
        self.offset = self.get_offset(request)
        self.request = request
        self.display_page_controls = False

        return list(queryset)


class SomeViewSet(viewsets.ModelViewSet):

    queryset = SomeModel.objects.all().order_by("-id")
    pagination_class = Unpaginated

The key here is to override the paginate_queryset function in base class and return the whole queryset.

However, overriding this function is not documented at all in the docs or I just missed it.

  1. https://www.django-rest-framework.org/api-guide/pagination/
  2. https://github.com/encode/django-rest-framework/blob/master/rest_framework/pagination.py
ospider
  • 9,334
  • 3
  • 46
  • 46
0

I solve this problem in the following way:

  • make your own pagination class and inherit it from PageNumberPagination
  • redefine or add your code (with super()) in get_page_size function.

For me works this case:

def get_page_size(self, request): super().get_page_size(request) ....... self.page_size = self.max_page_size return self.page_size

Tim Uzlov
  • 181
  • 2
  • 6