欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DRF(Django RestFramework)视图集总结

程序员文章站 2022-07-12 11:11:42
...

视图集

视图集有四个封装类,ViewSet基础封装、GenericViewSet进一步封装查询集和序列化器、ModelViewSet进一步封装action、ReadOnlyModelViewSet提取只读action。以下是展开介绍。

一、ViewSet

# 源码
class ViewSet(ViewSetMixin, views.APIView):
    pass

没错,源码中ViewSet就是只有继承而没有实现任何方法&定义任何属性,我们对APIView已经不陌生了,我上一篇DRF类视图中有,它主要实现请求,响应,验证,异常,限流等。主要看ViewSetMixin类。

class ViewSetMixin(object):
    """
    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.
    For example
    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    重写了as_view方法,它需要执行一个`actions`关键字
     HTTP方法绑定到资源上的操作
    """
    def as_view(cls, actions=None, **initkwargs)
	    # 有兴趣可以具体看实现,这里就不复制了
	    pass 

由源码可以看出,仅仅提供了as_view方法将请求方法绑定到了actions关键字上,并没有给出actions的具体实现,所以我们在使用ViewSet的时候,需要自己定义出action方法(查询集和序列化器需要手动实例化调用、异常抛出等),然后通过as_view绑定请求方法即可。

# 举例1.1
# 继承视图集ViewSet
class BooksAPIViewSet(ViewSet):
    # 定义action中的list实现查询所有
    def list(self, request):
	    # 手动实现查询集
        books = BookInfo.books.all()
        # 手动使用序列化器
        serializer = BookInfoModelSerializer(books, many=True)
        # 返回响应,APIView中实现的Response响应对象
        return Response(serializer.data)

    # 定义action中的retrieve检索条件
    def retrieve(self, request, pk):
        try:
            book = BookInfo.books.get(id=pk)
        except BookInfo.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        serializer = BookInfoSerializer(book)
        return Response(serializer.data)

我们实现了视图集,为了使他生效,我们还需要指定他们的url。

# as_view中实现了get->list的绑定,是我们发送的get /books/请求能够生效
url(r'^books/$', views.BooksAPIViewSet.as_view({'get': 'list'})),
# 绑定get->retrieve,使得get /books/id/生效
url(r'^books/(?P<pk>\d+)/$', views.BooksAPIViewSet.as_view({'get': 'retrieve'})),

综上:继承ViewSet,需要自定义action,action中需要自己实现查询集和序列化器,url中as_view需要绑定方法和action的对应关系

二、GenericViewSet

# 源码
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    pass

同样GenericViewSet类中也没有任何实现,全部继承自ViewSetMixin和GenericAPIView。DRF类视图中有GenericAPIView的介绍,它主要实现指定查询集queryset/get_queryset/get_object和指定序列化器serializer_class/get_serializer_class等。ViewSetMixin类刚刚提过主要重写实现了as_view()用于request方法和action的绑定。注意:GenericViewSet一般需要和5种扩展类执行。

# 举例1.2
# 继承视图集GenericViewSet
class BooksAPIViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    # 指定查询集和序列化器
    # 之所以不用定义get/post方法,是因为重写了as_view方法,将get映射为了list方法
    # 之所以不用第一action,是因为继承了ListModelMixin等扩展类
    queryset = BookInfo.books.all()
    serializer_class = BookInfoModelSerializer

三、ModelViewSet

# 源码
class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
	 pass

同样,我们的ModelViewSet中也没有任何功能的具体实现,单纯的继承五个扩展类的功能和GenericViewSet的功能。很明显,五个扩展类主要实现了Create(增)List/Retrieve(查)Update(改)Destroy(删)。GenericViewSet主要实现了序列化器的指定,查询集的指定,和as_view的重写。

四、ReadOnlyModelViewSet

# 源码
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet):
	pass

由此可以看出ReadOnlyModelViewSet仅仅是查询集。

相关标签: 类视图集