SirSaleh
SirSaleh

Reputation: 1614

Disable pagination when not requesting any page in djangorestframework

I wrote a pagination class like below for a ListView API.

class PhotoListPagination(PageNumberPagination):
   page_size = 100
   page_size_query_param = 'page_size'
   max_page_size = 10000

and use it in my API view as pagination_class:

class UserSinglePhotoAPIView(ListAPIView):
    model = Photo
    serializer_class = PhotoSerializer
    pagination_class = PhotoListPagination

    def get_queryset(self):
        return Profile.objects.get(auth_user__username=self.kwargs['username']).get_single_photos()

as I send a GET request to /link/to/my/API/end-point?page=1 or any other page number, it works pretty well. currently when page has no value (sending request to /link/to/my/API/end-point) it shows page 1. But I need to have all the results without pagination when I not set page key in the request.

Is it possible?

Any help will be appreciated.

Upvotes: 2

Views: 4540

Answers (4)

Parsa Dany
Parsa Dany

Reputation: 35

with many thanks to this answer that worked without any changes, if you are using LimitOffsetPagination you can use this:

class UserListAPIView(generics.ListAPIView):
    serializer_class = UserAPISerializer

    queryset = User.objects.all()
    

    pagination_class = LimitOffsetPagination

    def paginate_queryset(self, queryset):
        if self.paginator and self.request.query_params.get(self.paginator.limit_query_param, None) is None:
            return None
        return super().paginate_queryset(queryset)

Upvotes: 0

Magnus
Magnus

Reputation: 3722

My approach is similar to @Enthusiast Martin, except this will give you a consistent format of paginated results (with count, results, etc. as fields):

    def list(self, request, *args, **kwargs):
        files = File.objects.all()
        paginator = PageNumberPagination()

        if 'page' in request.query_params:
            paginator.page_size = 10
        else:
            paginator.page_size = 999999999999999999

        result_page = paginator.paginate_queryset(files, request)
        serializer = self.serializer_class(result_page, many=True)
        return paginator.get_paginated_response(serializer.data)

Upvotes: 0

Ehsan Nouri
Ehsan Nouri

Reputation: 2040

this is the paginate_queryset method in generic views,

def paginate_queryset(self, queryset):
    """
    Return a single page of results, or `None` if pagination is disabled.
    """
    if self.paginator is None:
        return None
    return self.paginator.paginate_queryset(queryset, self.request, view=self

so if this function returns None, the ListView will return a single page including all of the results, so override this method as below:

class UserSinglePhotoAPIView(ListAPIView):
    ...
    ...
    def paginate_queryset(self, queryset):
        if self.paginator and self.request.query_params.get(self.paginator.page_query_param, None) is None:
            return None
        return super().paginate_queryset(queryset)

Upvotes: 7

Enthusiast Martin
Enthusiast Martin

Reputation: 3091

You can override list method in your UserSinglePhotoAPIView, and do the pagination only when page query param is provided. Otherwise return all.

Something like this:

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    if 'page' in request.query_params:
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

Upvotes: 2

Related Questions