Python Django Rest框架-APIView分页

Python Django Rest框架-APIView分页,python,django,pagination,django-rest-framework,Python,Django,Pagination,Django Rest Framework,我有一个非常简单的APIView,但我不知道如何在这里设置分页。 在这个场景中,我选择一个具有给定pk的事件,然后获得分配给该事件的所有新闻项 pagination\u class=LimitOffsetPagination在ListCreateAPIView的开头定义queryset时可以正常工作,例如queryset=Event.objects.all()但不使用自定义get: class EventNewsItems(APIView): pagination_class = Lim

我有一个非常简单的
APIView
,但我不知道如何在这里设置分页。 在这个场景中,我选择一个具有给定
pk
事件
,然后获得分配给该
事件的所有
新闻项

pagination\u class=LimitOffsetPagination
ListCreateAPIView
的开头定义queryset时可以正常工作,例如
queryset=Event.objects.all()
但不使用自定义
get

class EventNewsItems(APIView):
    pagination_class = LimitOffsetPagination

    def get(self, request, pk, format=None):

        #user = request.user
        event = Event.objects.get(pk=pk)
        news = event.get_news_items().all()

        serializer = NewsItemSerializer(news, many=True, context={'request':request})
        response = Response(serializer.data, status=status.HTTP_200_OK)
        return response

已解决:

def get(self, request, pk, format=None):

    #user = request.user
    event = Event.objects.get(pk=pk)
    news = event.get_news_items().all()
    paginator = LimitOffsetPagination()
    result_page = paginator.paginate_queryset(news, request)
    serializer = NewsItemSerializer(result_page, many=True, context={'request':request})
    response = Response(serializer.data, status=status.HTTP_200_OK)
    return response
我在这个问题上做了很多工作。
作为排序摘要:

通过利用Django Rest Framework源代码以及它们如何处理分页,我们在视图类中创建了相同的方法,并使用它们,就像您的解决方案使用默认方法一样:

摘自上述文件:

from rest_framework.settings import api_settings
from rest_framework.views import APIView

class MyView(APIView):
    queryset = OurModel.objects.all()
    serializer_class = OurModelSerializer
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS # cool trick right? :)

    # We need to override get method to achieve pagination
    def get(self, request):
        ...
        page = self.paginate_queryset(self.queryset)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        ... Do other stuff needed (out of scope of pagination)

    # Now add the pagination handlers taken from 
    #  django-rest-framework/rest_framework/generics.py

    @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) 

另一个选项是从分页类继承,对视图类的更改更少:

来自rest_framework.pagination导入限制OffsetPagination
类EventNewsItems(APIView、LimitOffsetPagination):
def get(自我、请求、主键、格式=无):
event=event.objects.get(pk=pk)
news=event.get_news_items().all()
结果=self.paginate_queryset(新闻、请求、视图=self)
serializer=NewsItemSerializer(结果,多个=True)
返回self.get_分页的_响应(serializer.data)

另一种分页方法是使用Paginator类

除了回答查询外,还必须设置要显示的页数以及页面将包含的元素范围

页码和项目范围可以作为请求参数的一部分提供,也可以通过您选择的方式提供

以问题为例:

from django.core.paginator import Paginator

class EventNewsItems(APIView):

    def get(self, request, pk, format=None):

        #user = request.user
        event = Event.objects.get(pk=pk)
        news = event.get_news_items().all()

         # -----------------------------------------------------------
        page_number = self.request.query_params.get('page_number ', 1)
        page_size = self.request.query_params.get('page_size ', 10)

        paginator = Paginator(news , page_size)
        serializer = NewsItemSerializer(paginator.page(page_number) , many=True, context={'request':request})
        # -----------------------------------------------------------

        response = Response(serializer.data, status=status.HTTP_200_OK)
        return response

回顾这个讨论,看起来这家伙解决了你的问题嘿,@user3128673我想知道你是否觉得我的答案有用。
self.\u paginator=self.pagination\u class()。TypeError:“list”对象不可调用
-我收到此错误。缩进有点不正确though@GiannisKatsini诚然(我想我已经解决了所有问题)可以随意编辑任何你认为关闭的内容。谢谢!有没有一种方法可以在每个视图的基础上设置默认的限制和偏移量?Peter Paul的回答让我的评论过时了如果你想在每个视图的基础上处理限制和偏移量,那太好了!如果请求的页面为空,则会出现异常。您需要处理
django.core.paginator.EmptyPage
异常