Django Rest framework视图集-----ViewSet

视图集ViewSet

使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

  • list() 提供一组数据
  • retrieve() 提供单个数据
  • create() 创建数据
  • update() 保存数据
  • destory() 删除数据

1. 常用视图集父类

1) ViewSet

继承自APIViewViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。

ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{'get':'list'})的映射处理工作。

在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

2)GenericViewSet

使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView

GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIViewViewSetMixin,在实现了调用as_view()时传入字典(如{'get':'list'})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

代码应用:

# 视图集(获取所有,获取单一)
# url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),  # book-list
# url(r'^books/(?P\d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),  #book-retrieve
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins

from .models import BookInfo, HeroInfo
from .serializers import BookInfoSerializer

class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

3)ModelViewSet

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

4)ReadOnlyModelViewSet

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。

代码应用:

from rest_framework.viewsets import ReadOnlyModelViewSet

from .models import BookInfo, HeroInfo
from .serializers import BookInfoSerializer

# ReadOnlyModelViewSet包含上面继承的三个类
class BookInfoModelViewSet(ReadOnlyModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

2. 视图集中定义附加action动作

在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。

# todo:action装饰器
from rest_framework.decorators import action
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins

from .models import BookInfo, HeroInfo
from .serializers import BookInfoSerializer


class BookInfoViewSetAction(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    queryset = BookInfo.objects.all()

    def get_serializer_class(self):
        if self.action == 'read':
            return BookReadSerializer
        else:
            return BookInfoSerializer

    @action(methods=['get'], detail=False)
    def latest(self, request):
        """
        返回最新的书籍
        :param request:
        :return:
        """
        book = BookInfo.objects.latest('id')
        serializer = self.get_serializer(book)
        return Response(serializer.data)

    @action(methods=['put'], detail=True)
    def read(self, request):
        """
        修改书记的阅读量
        :param request:
        :return:
        """

        book = self.get_object()
        serializer = self.get_serializer(instance=book, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

 

你可能感兴趣的:(Python,DRF)