74π
Pagination is only performed automatically if youβre using the generic
views or viewsets
The first roadblock is translating the docs to english. What they intended to convey is that you desire a generic viewset. The generic viewsets extend from generic ApiViews which have extra class methods for paginating querysets and responses.
Additionally, youβre providing your own list
method, but the default pagination process is actually handled by the mixin:
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
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)
The easy solution, use the framework code:
class Foo(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = User.objects.all()
serializer = UserSerializer
The more complex solution would be if you need a custom list
method, then you should write it as you see fit but in the style of the above mixin code snippet.
95π
For those using DRF 3.1 or higher, they are changing the default way pagination is handled. See http://www.django-rest-framework.org/topics/3.1-announcement/ for details.
Now if you want to enable pagination for a ModelViewSet you can either do it globally by setting in your settings.py file:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
Or if you just want it for one ModelViewSet you can manually set the pagination_class for just that viewset.
from rest_framework.pagination import PageNumberPagination
class StandardResultsSetPagination(PageNumberPagination):
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 1000
class FooViewSet(viewsets.ModelViewSet):
pagination_class = StandardResultsSetPagination
This also allows you to tweak the way the pagination is handled for just that viewset.
DRF 3.1 also has introduced new types of default pagination schemes that you can use such as LimitOffset and Cursor.
- [Django]-How to access request body when using Django Rest Framework and avoid getting RawPostDataException
- [Django]-Disabled field is not passed through β workaround needed
- [Django]-CSRF Failed: CSRF token missing or incorrect
8π
Try providing a class variable
paginate_by = 10 #This will paginate by 10 results per page.
Create a Custom ViewSet
which performs only list
operation as your case for here currently.
class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
pass
Now inherit your class Foo
with this custom made viewset
class Foo(ListModelViewSet):
paginate_by = 10
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
This should help you get the pagination working.
- [Django]-In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?
- [Django]-Django: Catching Integrity Error and showing a customized message using template
- [Django]-Check permission inside a template in Django
7π
This way also worked in Django Rest apiViews Apiβs
from rest_framework.pagination import PageNumberPagination
class FooList(APIView):
page_size = 10
def get(self, request):
foo = Foo.objects.all()
paginator = PageNumberPagination()
paginator.page_size = page_size
result_page = paginator.paginate_queryset(foo, request)
serializer = FooSerializer(result_page, many=True)
return paginator.get_paginated_response(serializer.data)
- [Django]-Django return file over HttpResponse β file is not served correctly
- [Django]-'staticfiles' is not a valid tag library: Template library staticfiles not found
- [Django]-Get the list of checkbox post in django views
4π
Pagination in DRF using viewsets
and list
.
Here I have handled a exception If page is empty it will show empty records.
In setting define the page size, this page size is global and it is used by paginator_queryset
in view.
REST_FRAMEWORK = { βPAGE_SIZEβ: 10, }
In view.py:
from rest_framework import mixins, viewsets
class SittingViewSet(viewsets.GenericViewSet,
mixins.ListModelMixin):
serializer_class = SittingSerializer
queryset = Sitting.objects.all()
serializer = serializer_class(queryset, many=True)
def list(self, request, *args, **kwargs):
queryset =self.filter_queryset(Sitting.objects.all().order_by('id'))
page = request.GET.get('page')
try:
page = self.paginate_queryset(queryset)
except Exception as e:
page = []
data = page
return Response({
"status": status.HTTP_200_OK,
"message": 'No more record.',
"data" : data
})
if page is not None:
serializer = self.get_serializer(page, many=True)
data = serializer.data
return self.get_paginated_response(data)
# serializer = self.get_serializer(queryset, many=True)
return Response({
"status": status.HTTP_200_OK,
"message": 'Sitting records.',
"data" : data
})
Note: If you not use Order_by
it will show exception
because this list
gives unordered list.
- [Django]-Django: why i can't get the tracebacks (in case of error) when i run LiveServerTestCase tests?
- [Django]-Can't connect to local MySQL server through socket '/tmp/mysql.sock
- [Django]-Django test app error β Got an error creating the test database: permission denied to create database
4π
A slightly simpler variation on this answer if you want pagination for a particular ViewSet
, but donβt need to customize the page size:
REST_FRAMEWORK = {
'PAGE_SIZE': 100
}
class FooViewSet(viewsets.ModelViewSet):
pagination_class = PageNumberPagination
- [Django]-How do you detect a new instance of the model in Django's model.save()
- [Django]-Django auto_now and auto_now_add
- [Django]-How to check Django version
2π
Custom Pagination using GenericAPIView
1.view.py file
class ModelView(GenericAPIView):
pagination_class = CustomPagination
def post(self, request):
data = request.data
example_data = data.get('comment_id')
replies = ExampleModel.objects.filter(model_field=example_data).order_by('-id')
if replies.exists():
replies = self.paginate_queryset(replies)
replies = self.get_paginated_response(replies)
return replies
else:
return Response({'message': 'This is the reply message!'}, status=status.HTTP_200_OK)
2.pagination.py file
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 1000
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.page.next_page_number() if self.page.has_next() else None,
'previous': self.page.previous_page_number() if self.page.has_previous() else None
},
'total': self.page.paginator.count,
'page': int(self.request.GET.get('page', 1)),
'page_size': int(self.request.GET.get('page_size', self.page_size)),
'results': ModelSerializer(data, context={'request':self.request}, many=True).data
}, status=status.HTTP_200_OK)
3.my_serializer.py file
class ModelSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
def to_representation(self, instance):
ret = super().to_representation(instance)
request = self.context.get('request')
if instance.user_information.image else None
ret['user_name'] = instance.user_information.name
return ret
Itβs all that you need.
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
- [Django]-How can I test https connections with Django as easily as I can non-https connections using 'runserver'?
- [Django]-Django index page best/most common practice