Python 分页在DRF APIView中不起作用
我正在使用APIViewPython 分页在DRF APIView中不起作用,python,django,pagination,django-rest-framework,Python,Django,Pagination,Django Rest Framework,我正在使用APIView获取和发布项目。 我想使用Django Rest框架为我的API实现分页,但它不起作用 我想每页显示10个项目,但当我执行api/v1/items?page=1时,我会得到所有项目,如果我只执行api/v1/items我会得到一个空列表 以下是我所做的: from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger class ItemsAPIView(APIView): per
获取和发布项目。
我想使用Django Rest框架为我的API实现分页,但它不起作用
我想每页显示10个项目,但当我执行api/v1/items?page=1
时,我会得到所有项目,如果我只执行api/v1/items
我会得到一个空列表
以下是我所做的:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class ItemsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, format=None):
"""
Return a list of all items of this user.
"""
reply = {}
page = request.GET.get('page')
print ('page is', page)
try:
products = BaseItem.objects.owned_items().filter(owner=request.user)
reply['data'] = OwnedItemSerializer(products, many=True).data
items = BaseItem.objects.filter(owner=request.user)
paginator = Paginator(items, 1)
items_with_pagination = paginator.page(page)
if page is not None:
reply['data'].extend(ItemSerializer(items_with_pagination, many=True).data)
reply['data'].extend(ItemSerializer(items, many=True).data)
您可以使用ListView使您的生活更加轻松。通过覆盖render_to_响应,可以使其输出json而不是HTML。它为您完成所有分页
from django.core import serializers
from django.views.generic import ListView
class MyListView(JSONResponseMixin, ListView):
model = models.BaseItem
paginate_by = 10
def render_to_response(self, context):
return JsonResponse(
serializers.serialize("json", context),
**response_kwargs
)
django rest框架文档中所述的非通用视图和视图集:
仅当使用常规视图或视图集时,才会自动执行分页。如果您使用的是常规的APIView
,则需要自己调用分页API,以确保返回分页响应。有关示例,请参阅mixin.ListModelMixin
和generics.GenericAPIView
类的源代码
我编写了一个关于如何实现这一点的代码:
class ItemsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
serializer_class = MyNewUnifiedSerializerClass
def get(self, request):
user_items = BaseItem.objects.filter(
owner=request.user
).distinct()
page = self.paginate_queryset(user_items)
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(user_items, many=True)
return Response(serializer.data)
# 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)
有关更多详细信息,请查看扩展GenericAPIView
而不是apview
并在GenericAPIView
paginator=None中定义pagination_class
> class NotesViewSet(viewsets.ModelViewSet):
> queryset = Notes.objects.all()
> serializer_class = NotesWriteSerializer
> paginator = None
我的APIView中使用了两个序列化程序,还有一个扩展函数。这是不同的做法。如果只是使用model.objects.all(),我会更喜欢ListView。然后只需在get\u context\u data(self,**kwargs)中添加您需要的任何其他内容即可:
嘿,@pythonBeginner我想知道,您是否发现任何答案都有帮助?问题是关于APIView
的问题,而这个示例没有解决这个问题。