Django rest framework中ViewSet和GenericViewSet的区别

15

我有一个Django Rest Framework的 GenericViewset,现在我想要设置分页,具体如下:

#settings.py
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 
         'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20
}

#views.py
class PolicyViewSet(viewsets.GenericViewSet):
    def list(self, request):
        queryset = Policy.objects.all()
        page = self.paginate_queryset(queryset)
        serializer = PolicySerializer(page, many=True)
        return self.get_paginated_response(serializer.data)

这个按预期工作。然而,如果我尝试仅使用普通的视图集来执行相同的操作,如下所示:

#views.py
class PolicyViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Policy.objects.all()
        page = self.paginate_queryset(queryset)
        serializer = PolicySerializer(page, many=True)
        return self.get_paginated_response(serializer.data)

我遇到了一个错误:

'PolicyViewSet'对象没有'paginate_queryset'属性

我如何在普通的Viewset中设置分页?DRF中的GenericViewset和Viewset有什么区别?

4个回答

27

如果你正在使用通用视图或视图集,则分页将自动执行。

请阅读文档

回答你的第二个问题DRF中GenericViewset和Viewset之间的区别是什么?

DRF有两个主要系统来处理视图:

  1. APIView:提供了一些处理程序方法,以处理http动词:getpostputpatchdelete
  2. ViewSet:这是对APIView的抽象,它提供了操作作为方法:

    • list:只读,返回多个资源(http动词:get)。返回一个字典列表。
    • retrieve:只读,单个资源(http动词:get,但将期望一个id)。返回一个字典。
    • create:创建新资源(http动词:post
    • update/partial_update:编辑资源(http动词:put/patch
    • destroy:删除资源(http动词:delete
  3. GenericViewSet:有许多通用视图集,最常见的是ModelViewSet。它们继承自GenericAPIView,并具有所有操作的完整实现:listretrievedestroyupdated等。当然,您也可以选择其中的一些,阅读文档


1
那么,我如何在我的问题中使用视图集执行分页? - Amistad
@Amistad 请使用以下代码对视图集进行分页处理:return self.get_paginated_response(self.paginate_queryset(serializer.data)) - Nwawel A Iroume

1

来自Django Rest Framework源代码:

class ViewSet(ViewSetMixin, views.APIView):
    """
    The base ViewSet class does not provide any actions by default.
    """
    pass


class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass

class GenericAPIView(views.APIView):
    """
    Base class for all other generic views.
    """

APIView不包含分页,它是在GenericAPIView中实现的。

要在ViewSet中使用分页,您应该设置分页类并遵循GenericAPIView的源代码。

GenericAPIView包含额外的代码,使其更加结构化。在通常情况下,GenericAPIView使用更少的代码执行相同的任务。对于复杂的场景,当您想要自定义更多内容时,GenericAPIView将不提供任何额外的优势。


1

只需从GenericViewSet继承即可。

#views.py
class PolicyViewSet(viewsets.ViewSet, viewsets.GenericViewSet):
    def list(self, request):
        queryset = Policy.objects.all()
        page = self.paginate_queryset(queryset)
        serializer = PolicySerializer(page, many=True)
        return self.get_paginated_response(serializer.data)

0
如何在普通的Viewset中设置分页?
如果您想在Viewset中使用“pagination_class”,那么您应该使用GenericViewSet而不是ViewSet。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接