Django REST框架:泛型或ModelViewSets?

dt0*_*xff 9 python django rest django-rest-framework

我使用泛型和普通URL作为我的REST API,但现在我遇到了问题:我想要自定义操作,简单的视图来为我的模型做一些事情,比如"运行","发布"等.

ViewSetaction装饰者创建自定义动作,但只有在ViewSets中,还有步进路由器,这使我们能够使用railsish convention-over-configuration简化所有操作.

但我发现这ModelViewSet给了我们相同的能力,如泛型:完整的CRUD,序列化器,过滤器,cusstom前/后和查询集,所以,它会导致问题:

为什么有泛型,如果ModelViewSet给予相同的能力和更多?有什么区别?

lev*_*evi 13

不同之处在于它们提供的方法.

例如:

GenericViewSet继承自GenericAPIView,但不提供任何基本操作的实现.只有get_object,get_queryset.

ModelViewSet 继承自GenericAPIView,包括各种操作的实现.换句话说,您不需要实现基本操作作为列表,检索,创建,更新或销毁.当然,您可以覆盖它们并实现您自己的列表或您自己的创建方法.

您可以在API REFERENCE部分:ModelViewSet中阅读有关它的更多信息

  • 我想知道ModelViewSet和像ListCreateAPIView这样的泛型之间的区别 (2认同)

Tom*_*tie 7

如果 ModelViewSet 提供相同甚至更多的功能,为什么还要有泛型呢?

让我首先为您更明确地重新表述一下这个问题......

“既然也有通用视图集,为什么还要有通用视图”

这实际上归结为为什么 REST 框架同时支持视图和视图集的问题。答案 - ViewSet 对于原型设计或当您的 API URL 整齐地映射到整个固定约定(例如 CRUD 样式 API)时非常有用。视图对于明确显示很有用,或者在您的 URL 没有完全映射到固定约定的情况下非常有用。


小智 6

GenericsModelViewSet的区别在于:

  1. 方便
    通常ModelViewSet更方便。因为ModelViewSet支持使用 DRF 路由器自动创建 url 模式。但泛型没有。你自己做。

  2. 缩短和脆化代码
    如果要创建 CRUD,泛型需要两个类(ListCreateAPIView 和 RetrieveUpdateDestroyAPIView)。但是ModelViewSet只需要一个类(ModelViewSet)。

查看下面的声明。两者都继承自GenericAPIViewmixins.CreateModelMixinmixins.ListModelMixin基本提供了等价的功能。这取决于你喜欢什么。但我通常在大多数情况下使用 ViewSet。


宣言

# Generics __________________________________
class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin, 
                        GenericAPIView):

# ModelViewSet _____________________________
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):

# GenericViewSet _____________________________
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
Run Code Online (Sandbox Code Playgroud)

示例代码

# Generics __________________________________
from rest_framework import generics

class BookList(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

# ModelViewSet _____________________________
from rest_framework import viewsets

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
Run Code Online (Sandbox Code Playgroud)