Last active
August 29, 2015 14:17
-
-
Save edgartaor/6cfd8e4fd34307096a22 to your computer and use it in GitHub Desktop.
Paginaton in nested view in ViewSet in custom route [Django - Rest Framework]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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