Подтвердить что ты не робот

Django Rest Framework: включите разбиение на страницы на ViewSet (например, разбиение на страницы ModelViewSet)

У меня есть ViewSet, как этот, чтобы перечислять данные пользователей:

class Foo(viewsets.ViewSet):

    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

Я хочу включить разбивку на страницы так же, как разбиение на страницы по умолчанию для ModelViewSet:

{
    "count": 55,
    "next": "http://myUrl/?page=2",
    "previous": null,
    "results": [{...},{...},...,{...}]
}

В официальном документе говорится:

Разметка выполняется только автоматически, если вы используете общие представления или виды.

... но мои результаты не разбиты на страницы. Как его можно разбивать на страницы?

4b9b3361

Ответ 1

Разметка только выполняется автоматически, если вы используете общий просмотров или просмотров.

Первый roadblock переводит документы на английский. То, что они намеревались передать, - это то, что вы желаете общий вид. Общие представления распространяются от общих ApiViews, которые имеют дополнительные методы класса для разбивки запросов и ответов.

Кроме того, вы предоставляете свой собственный метод list, но процесс разбивки по умолчанию на самом деле обрабатывается 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)

Простое решение, используйте код рамки:

class Foo(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = User.objects.all()
    serializer = UserSerializer

Более сложное решение было бы, если вам нужен пользовательский метод list, тогда вы должны написать его, как вы сочтете нужным, но в стиле приведенного выше фрагмента кода mixin.

Ответ 2

Для тех, кто использует DRF 3.1 или выше, они меняют способ разбивки по страницам по умолчанию. Подробнее см. http://www.django-rest-framework.org/topics/3.1-announcement/.

Теперь, если вы хотите включить разбивку на страницы для ModelViewSet, вы можете сделать это глобально, установив в файле settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100
}

Или, если вы просто хотите его для одного ModelViewSet, вы можете вручную установить pagination_class только для этого вида.

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

Это также позволяет вам настроить способ обработки постраничного изображения только для этого вида.

DRF 3.1 также представила новые типы схем разбивки по умолчанию, которые вы можете использовать, например LimitOffset и Cursor.

Ответ 3

Попробуйте предоставить переменную класса

paginate_by = 10 #This will paginate by 10 results per page.

Создайте пользовательский ViewSet, который выполняет только list операцию как ваш случай для здесь в настоящее время.

class ListModelViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    pass

Теперь наследуем ваш класс Foo с помощью этого настраиваемого вида view

class Foo(ListModelViewSet):

    paginate_by = 10

    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

Это поможет вам получить разбивку на страницы.

Ответ 4

Разбиение страницы в DRF с использованием видов и списка

Здесь я обработал исключение. Если страница пуста, она будет показывать пустые записи

В настройке задайте размер страницы, этот размер страницы является глобальным и используется paginator_queryset в поле зрения

REST_FRAMEWORK = {'PAGE_SIZE': 10,}

В поле зрения   из rest_framework импортирует mixins, viewets

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_404_NOT_FOUND,
                "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
        })

** > Примечание. Если вы не используете Order_by, он отобразит исключение, потому что этот список

дает неупорядоченный список. **