Reputation: 845
I have a function based Django API as shown in this sample:
@api_view(['GET'])
def findData(request):
dataId = request.GET['dataId']
page_query_param = 'page'
page_size = request.GET['page_size']
paginator = PageNumberPagination()
paginator.page_size = page_size
paginator.page_query_param = page_query_param
qry_set = Data.objects.all()
serializer = dataIdSerializer(qry_set, many=True)
theData= serializer.data
return Response(paginator.get_paginated_response(theData))
But I keep getting this error:
AttributeError: 'PageNumberPagination' object has no attribute 'page'
I tried setting
paginator.page_query_param = page_query_param
But still same problem. Please advise of how to fix.
Upvotes: 5
Views: 7015
Reputation: 17
Need to add DEFAULT_PAGINATION_CLASS & PAGE_SIZE values in REST_FRAMEWORK dictionary which is in settings.py of your project.
i.e
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 5
}
Upvotes: 0
Reputation: 322
For me adding this to the settings.py
fixed the issue.
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10 # the size of one page
}
Upvotes: 0
Reputation: 141
The problem is that page
is set on PageNumberPagination
when .paginate_queryset()
is called.
Therefore, you need to call .paginate_queryset()
on your paginator
and pass the queryset
and the request
.
When you instantiate your serializer, pass the result you got from calling .paginate_queryset()
instead of qry_set
Once you're done with that, DRF will throw another exception since you put paginator.get_paginated_response(theData)
in Response
. To resolve that, just return paginator.get_paginated_response(theData)
.
And finally your code will look like this:
def findData(request):
dataId = request.GET['dataId']
page_query_param = 'page'
page_size = request.GET['page_size']
paginator = PageNumberPagination()
paginator.page_size = page_size
paginator.page_query_param = page_query_param
qry_set = Data.objects.all()
p = paginator.paginate_queryset(queryset=qry_set, request=request) # change 1
serializer = dataIdSerializer(p, many=True) # change 2
theData= serializer.data
return paginator.get_paginated_response(theData) # change 3
Upvotes: 7
Reputation: 477513
It is likely more effective to use a ListView
, not only this will remove a lot of boilerplate code, but also is likely less error prone. You can just subclass the paginator to your own:
class MyPaginator(PageNumberPagination):
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 1000
Then in the ListView
, we can make use of the MyPaginator
:
from rest_framework import generics
class DataListView(generics.ListAPIView):
queryset = Data.objects.all()
serializer_class = dataIdSerializer
pagination_class = MyPaginator
def get_queryset(self, *args, **kwargs):
dataId = self.request.GET['dataId']
super().get_queryset(*args, **kwargs).filter(
# …
)
Here you can filter the queryset in the get_queryset
method to only use Data
objects that satisfy a given condition.
In the urls, you can then finally link it with .as_view()
:
urlpatterns = [
path('/findData', DataListView.as_view())
]
Upvotes: 1