Django rest framework: how to turn off/on pagination in ModelViewSet

Viewed 7313

I'm using Django REST framework with djangorestframework-csv with default pagination settings, but when request is with format "CSV", there is no need in paginaion. Is possible to disable pagination with:

pagination_class = None

it's possible to change it dynamically?

class ObjectViewSet(BaseViewSet, viewsets.ModelViewSet):

    queryset = Object.objects.none()
    serializer_class = ObjectSerializer
    pagination_class = None # if format is "CSV"
    # pagination_class = None # if fromat isn't "CSV"

Thanks.

7 Answers

This solution is working for me

DRF Version: 3.11.0

Django Version: 2.2.7

By default pagination is working but when I will pass the query param 'no_page' then pagination will be disabled: like: http://localhost:8000/api/city/?no_page

class CityListView(generics.ListCreateAPIView):
    serializer_class = serializers.CitySerializer
    def paginate_queryset(self, queryset, view=None):
        if 'no_page' in self.request.query_params:
            return None
        else:
            return self.paginator.paginate_queryset(queryset, self.request, view=self)

simply you can use pagination_class = None inside your class:

class MyClassBasedView(ModelViewSet):
    pagination_class = None

It doesn't work anymore (at least not in latest version), you should do something like

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

and call the function with self.paginate_queryset(queryset, request) when inside the list method

Perhaps a more future-proof approach - open up my_venv/lib/python3.8/site-packages/rest_framework/generics.py - replacing my_venv and your Python version, scroll to around line 165 and copy the method signature for paginate_queryset. Also check what it returns if self.paginator is None - that is what to return if you want to disable pagination.

On DRF 3.11 the parent method signature is paginate_queryset(self, queryset), and if self.paginator is None it returns None, so I used:

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

I haven't tested it but I guess the answer to the OP question is (assuming a fairly default DRF config):

if ('format' in self.request.query_params and 
        self.request.query_params['format'] == 'csv'):
Related