Christian Rapp Christian Rapp - 3 months ago 23
Python Question

Change pagination based on user status with django rest framework

I try to set the pagination of my WebAPI based on the status of a User. If the user

is_anonymous
he should not be able to set the page size with a query parameter. I try to do this with one view class. I could do it with two different view classes and limit the access to one of them, but I think this is not a good solution.

View Class:

class WeathermList(generics.ListAPIView):
queryset = WeatherMeasurements.objects.all()
serializer_class = WeatherMeasurementsSer
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
filter_class = WeatherMeasurementsFilter
ordering_fields = ('measure_datetime',)
ordering = ('measure_datetime',)

@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
# import ipdb
# ipdb.set_trace()
if self.request.user.is_anonymous:
self._paginator = AnonymousPaginator
else:
self._paginator = RegisteredPaginator
return self._paginator


Pagination classes:

class RegisteredPaginator(PageNumberPagination):
page_size = 288
page_size_query_param = 'page_size'
max_page_size = 10000


class AnonymousPaginator(PageNumberPagination):
page_size = 288


Error message:

File ".../env/lib/python3.5/site-packages/rest_framework/generics.py", line 172, in paginate_queryset
return self.paginator.paginate_queryset(queryset, self.request, view=self)
TypeError: paginate_queryset() missing 1 required positional argument: 'request'


The
property paginator
is originally declared in class GenericAPIView. I am not sure if I reimplement it correctly. Both Custom pagination classes of mine are working when I set them using
pagination_class


Any help to get this working is greatly appreciated.

Answer

The problem is: self._paginator needs a paginator class instance, not a class itself

It should be AnonymousPaginator()and RegisteredPaginator(), not AnonymousPaginator, RegisteredPaginator.

        if self.request.user.is_anonymous:
            self._paginator = AnonymousPaginator()
        else:
            self._paginator = RegisteredPaginator()