我有一个非常简单的APIView
,但我不知道如何在这里设置分页。
在这种情况下,我选择了Event
给定的pk
,然后我获得了分配给此NewsItems
的所有Event
。
pagination_class = LimitOffsetPagination
的开头定义queryset时, ListCreateAPIView
正常工作。 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
答案 0 :(得分:8)
我在这个主题上创建了一个Q&A style example 作为一种总结:
通过使用Django Rest Frameworks源代码以及它们如何处理分页,我们在视图类中创建相同的方法并使用它们,就像您的解决方案使用默认方法一样:
取自上述文件:
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)
答案 1 :(得分:3)
另一种分页方法是使用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
答案 2 :(得分:0)
另一个选项将从分页类继承,而对视图类的更改较少:
class EventNewsItems(APIView, LimitOffsetPagination):
def get(self, request, pk, format=None):
event = Event.objects.get(pk=pk)
news = event.get_news_items().all()
results = self.paginate_queryset(news, request, view=self)
serializer = NewsItemSerializer(results, many=True)
return self.get_paginated_response(serializer.data)