Django rest框架中ViewSet和GenericViewSet的区别

Posted

技术标签:

【中文标题】Django rest框架中ViewSet和GenericViewSet的区别【英文标题】:Difference between ViewSet and GenericViewSet in Django rest framework 【发布时间】:2019-07-09 05:06:45 【问题描述】:

我有一个 Django 休息框架 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)

这按预期工作。但是,如果我尝试仅使用普通 Viewset 执行相同操作,如下所示:

#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 有什么区别?

【问题讨论】:

【参考方案1】:

仅当您使用泛型时才会自动执行分页 视图或视图集

阅读docs

回答你的第二个问题DRF中的GenericViewset和Viewset有什么区别

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

    APIView:这提供了一些处理方法,用于处理 http 动词:getpostputpatchdelete

    ViewSet:这是对 APIView 的抽象,它提供 actions 作为方法:

    list:只读,返回多个资源(http 动词:get)。返回字典列表。 retrieve:只读,单一资源(http 动词:get,但需要一个 id)。返回单个字典。 create:创建新资源(http 动词:postupdate/partial_update:编辑资源(http 动词:put/patchdestroy:删除资源(http 动词:delete

    GenericViewSet:有很多GenericViewSet,最常见的是ModelViewSet。它们继承自GenericAPIView 并完整实现了所有动作listretrievedestroyupdated 等。当然,您也可以选择一些其中,read the docs。

【讨论】:

那么如何使用我的问题中的视图集执行分页? @Amistad 使用以下代码对视图集进行分页 return self.get_paginated_response( self.paginate_queryset(serializer.data))【参考方案2】:

也只是从 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)

【讨论】:

【参考方案3】:

如何使用普通 Viewset 设置分页?

如果您想在视图集中使用“pagination_class”,那么您应该使用 GenericViewSet 而不是 ViewSet

【讨论】:

以上是关于Django rest框架中ViewSet和GenericViewSet的区别的主要内容,如果未能解决你的问题,请参考以下文章

ViewSet方法的Django rest框架permission_classes

django-rest-framework框架总结之View视图之APIViewGenericAPIView视图集ViewSet

Django REST Framework Viewset 返回 404(GET 请求)

Django REST框架--viewSets & Routers

django-rest-framework:每个 ViewSet 可以有多个模板吗?

在 Django Rest Framework 中使用 APIView 和 viewset 设置路由器