19

現在、次のように API ビューをセットアップしています。

class CartView(APIView):
    authentication_classes = [SessionAuthentication, TokenAuthentication]
    permission_classes = [IsAuthenticated, ]
    api_view = ['GET', 'POST']

    def get(self, request, format=None):
        try:
            cart = request.user.cart
        except Cart.DoesNotExist:
            cart = Cart.objects.create(user=request.user)
        cart_details = cart.cart_details.all()
        serializer = CartDetailSerializer(cart_details, many=True, fields=['id', 'item', 'quantity', 'product_type'])
        return Response(serializer.data)

CartDetailSerializerこれは通常の ModelSerializer です。

この API をページ付けしたいと思います。ただし、DRF のドキュメントでは、次のことがわかりました。

通常の APIView を使用している場合は、ページ分割された応答を確実に返すために、ページ分割 API を自分で呼び出す必要があります。

通常の APIView API をページ分割する方法の例は提供されていません。

上記のシナリオで使用できる例を誰でも投稿できますか。

ありがとう。

4

4 に答える 4

24

rayy が言及する方法は可能ですが、django-rest-framework は、API の操作をより簡単にするいくつかの追加機能を使用して、これを内部で処理できます。(* django-rest-framework のページネーションは、django.core.paginator の Django ページネーターから構築されていることに注意してください)

引用した直後に、この問題を解決するための重要な情報があります。

ページネーションは、汎用ビューまたはビューセットを使用している場合にのみ自動的に実行されます。通常の APIView を使用している場合は、ページ分割された応答を確実に返すために、自分でページ分割 API を呼び出す必要があります。例については、mixins.ListMixin および generics.GenericAPIView クラスのソース コードを参照してください。

そこに記載されている内容を少し修正します。ListModelMixin を見てください。

これら 2 つのリンクにアクセスすると、上記のファイルのソース コードが表示されます: generics.py mixins.py

APIView でページネーションを機能させるには、次のようなものを含める必要があります (**注: このコードはテストされていませんが、アイデアは正しいです。コードを含めるよりも、これを記述するより良い方法もあります。あらゆる観点からですが、私の答えを短く理解しやすいものにするために、それはあなたに任せます):

from __future__ import absolute_import
# if this is where you store your django-rest-framework settings
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response

from .models import Cart 

class CartView(APIView):
    pagination_class = settings.DEFAULT_PAGINATION_CLASS

    def get(self, request, format=None):
        #assuming every other field in the model has a default value    
        cart = Cart.objects.get_or_create(user=request.user)

        #for a clear example
        cart_details = Cart.objects.all()

        page = self.paginate_queryset(cart_details)
        if page is not None:
            serializer = CartDetailSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = CartDetailSerializer(cart_details, many=True)
        return Response(serializer.data)

    @property
    def paginator(self):
        """
        The paginator instance associated with the view, or `None`.
        """
        if not hasattr(self, '_paginator'):
            if self.pagination_class is None:
                self._paginator = None
            else:
                self._paginator = self.pagination_class()
        return self._paginator

    def paginate_queryset(self, queryset):
        """
        Return a single page of results, or `None` if pagination is disabled.
        """
        if self.paginator is None:
            return None
        return self.paginator.paginate_queryset(queryset, self.request, view=self)

    def get_paginated_response(self, data):
        """
        Return a paginated style `Response` object for the given output data.
        """
        assert self.paginator is not None
        return self.paginator.get_paginated_response(data)

これが、この投稿に出くわしたあなたや他の人にとってより役立つことを願っています.

于 2015-07-14T08:09:28.793 に答える
20

通常の APIView を使用する場合、Django 独自の Paginator クラスを使用する必要があります。

ビューの Django ページネーション

あなたの場合、クエリセットをシリアライザーに送信する前にページ付けできます。

このようなもの:

def get(self, request, format=None):
    try:
        cart = request.user.cart
    except Cart.DoesNotExist:
        cart = Cart.objects.create(user=request.user)
    cart_details = cart.cart_details.all()

    paginator = Paginator(cart_details, 10)
    page = request.GET.get('page')

    try:
        cart_details = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        cart_details = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        cart_details = paginator.page(paginator.num_pages)
    serializer = CartDetailSerializer(cart_details, many=True, fields=['id', 'item', 'quantity', 'product_type'])
    return Response(serializer.data)

お役に立てれば。

于 2015-03-16T08:51:56.933 に答える