web-dev-qa-db-ja.com

Django Rest Framework:ViewSetのページネーションをオンにします(ModelViewSetのページネーションと同様)

ユーザーのデータをリストするこのようなビューセットがあります:

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": [{...},{...},...,{...}]
}

公式ドキュメント 言います:

ページネーションは、汎用ビューまたはビューセットを使用している場合にのみ自動的に実行されます

...しかし、私の結果セットはまったくページ分割されていません。どうすればページ分割できますか?

30
floatingpurr

ページネーションは、汎用ビューまたはビューセットを使用している場合にのみ自動的に実行されます

最初の障害は、ドキュメントを英語に翻訳することです。彼らが伝えようとしたのは、一般的なビューセットを望んでいるということです。汎用ビューセットは、 generic 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コードスニペットのスタイルで記述する必要があります。

35
Mark Galloway

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
}

または、1つの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など、使用できる新しいタイプのデフォルトのページネーションスキームも導入されています。

28
jeffjv

クラス変数を提供してみてください

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

現在、ここでのケースとしてViewSet操作のみを実行するカスタムlistを作成します。

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

このカスタムメイドのビューセットでクラスFooを継承します

class Foo(ListModelViewSet):

    paginate_by = 10

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

これは、ページネーションを機能させるのに役立ちます。

3
Arpit Goyal

ビューセットとリストを使用したDRFのページネーション

ここで例外を処理しましたページが空の場合、空のレコードが表示されます

ページサイズを定義する設定では、このページサイズはグローバルで、paginator_querysetがビューで使用します

REST_FRAMEWORK = {'PAGE_SIZE':10、}

Rest_frameworkのインポートミックスイン、ビューセットからのビュー

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を使用しない場合、このリストのため例外が表示されます

順不同リストを提供します。**

2
Vinay Kumar

特定のViewSetのページネーションが必要だが、ページサイズをカスタマイズする必要がない場合、 この回答 のわずかに単純なバリエーション:

REST_FRAMEWORK = {
    'PAGE_SIZE': 100
}

class FooViewSet(viewsets.ModelViewSet):
    pagination_class = PageNumberPagination
1
morningstar