Skip to content

Instantly share code, notes, and snippets.

@edgartaor
Last active August 29, 2015 14:17
Show Gist options
  • Save edgartaor/6cfd8e4fd34307096a22 to your computer and use it in GitHub Desktop.
Save edgartaor/6cfd8e4fd34307096a22 to your computer and use it in GitHub Desktop.
Paginaton in nested view in ViewSet in custom route [Django - Rest Framework]
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger, InvalidPage
from django.http import Http404
from django.utils import six
from rest_framework import pagination
def get_paginated_serializer(queryset, request, serializer_class, context,
page_size=50, page_kwarg='page', *args, **kwargs):
'''Get paginated serializer loaded with all the data'''
paginator = Paginator(queryset, page_size)
page_kw = kwargs.get(page_kwarg)
page_query_param = request.query_params.get(page_kwarg)
page = page_kw or page_query_param or 1
try:
page_number = paginator.validate_number(page)
except InvalidPage:
if page == 'last':
page_number = paginator.num_pages
else:
raise Http404("Page is not 'last', nor can it be converted to an int.")
try:
queryset = paginator.page(page_number)
except InvalidPage as exc:
error_format = _('Invalid page (%(page_number)s): %(message)s')
raise Http404(error_format % {
'page_number': page_number,
'message': six.text_type(exc)
})
class PaginatedSerializer(pagination.PaginationSerializer):
class Meta:
object_serializer_class = serializer_class
serializer = PaginatedSerializer(instance=queryset, context=context)
return serializer
class UserViewSet(viewsets.ModelViewSet):
lookup_field = 'username'
serializer_class = UserSerializer
queryset = User.objects.all()
permission_classes = [IsAdminUserOrReadOnly]
@list_route(methods=['GET'], url_path='(?P<username>[^/]+)/items',
permission_classes=(permissions.AllowAny,))
def items(self, request, username=None, *args, **kwargs):
queryset = Items.objects.filter(user__username=username).select_related('images.count','images.first.thumb')
# Get the paginated serializer
serializer = utils.get_paginated_serializer(queryset, request, ItemSerializer, self.get_serializer_context(), 50)
if not serializer.data['results'] and not User.objects.filter(username=username).exists():
return Response(serializer.data, status=404)
return Response(serializer.data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment