1. [
  1. 课程介绍
  2. ](_index_)
    1. [
  1. 引入DjangoRESTframework
  2. ](c01-introducetodrf_index)
  3. -
  4. [
  5. Web应用模式
  6. ](c01-introducetodrf_separatedfrontendandbackend)
    1. [
  1. 认识RESTful
  2. ](c01-introducetodrf_introducetorest)
    1. [
  1. RESTful设计方法
  2. ](c01-introducetodrf_howtodesignrest)
    1. [
  1. 使用Django开发REST接口
  2. ](c01-introducetodrf_developrestapiwithdjango)
    1. [
  1. 明确REST接口开发的核心任务
  2. ](c01-introducetodrf_coretasktodeveloprestapi)
    1. [
  1. DjangoRESTframework简介
  2. ](c01-introducetodrf_aboutdrf)
    1. [
  1. DRF工程搭建
  2. ](c02-drfproject_index)
  3. -
  4. [
  5. 环境安装与配置
  6. ](c02-drfproject_installandconfig)
    1. [
  1. 见识DRF的魅力
  2. ](c02-drfproject_thefirstdrfprogram)
    1. [
  1. Serializer序列化器
  2. ](c03-serializer_index)
  3. -
  4. [
  5. 定义Serializer
  6. ](c03-serializer_declaring)
    1. [
  1. 序列化使用
  2. ](c03-serializer_serializing)
    1. [
  1. 反序列化使用
  2. ](c03-serializer_deserializing)
    1. [
  1. 模型类序列化器ModelSerializer
  2. ](c03-serializer_modelserializer)
    1. [
  1. 视图
  2. ](c04-view_index)
  3. -
  4. [
  5. RequestResponse
  6. ](c04-view_requestandresponse)
    1. [
  1. 视图概览
  2. ](c04-view_view)
    1. [
  1. 视图说明
  2. ](c04-view_viewintroduction)
    1. [
  1. 视图集ViewSet
  2. ](c04-view_viewset)
    1. [
  1. 路由Router
  2. ](c04-view_routers)
    1. [
  1. 其他功能
  2. ](c05-components_index)
  3. -
  4. [
  5. 认证
  6. ](c05-components_authentication)
    1. [
  1. 权限
  2. ](c05-components_permissions)
    1. [
  1. 限流
  2. ](c05-components_throttling)
    1. [
  1. 过滤
  2. ](c05-components_filtering)
    1. [
  1. 排序
  2. ](c05-components_ordering)
    1. [
  1. 分页
  2. ](c05-components_pagination)
    1. [
  1. 版本
  2. ](c05-components_versioning)
    1. [
  1. 异常处理
  2. ](c05-components_exceptions)
    1. [
  1. 自动生成接口文档
  2. ](c05-components_documents)
    1. [
    2. Published with GitBook
    3. ](https://www.gitbook.com)

课程介绍

视图集ViewSet

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

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

ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。如:

  1. class BookInfoViewSet(viewsets.ViewSet):
  2. def list(self, request):
  3. books = BookInfo.objects.all()
  4. serializer = BookInfoSerializer(books, many=True)
  5. return Response(serializer.data)
  6. def retrieve(self, request, pk=None):
  7. try:
  8. books = BookInfo.objects.get(id=pk)
  9. except BookInfo.DoesNotExist:
  10. return Response(status=status.HTTP_404_NOT_FOUND)
  11. serializer = BookInfoSerializer(books)
  12. return Response(serializer.data)

在设置路由时,我们可以如下操作

  1. urlpatterns = [
  2. url(r'^books/$', BookInfoViewSet.as_view({'get':'list'}),
  3. url(r'^books/(?P<pk>\d+)/$', BookInfoViewSet.as_view({'get': 'retrieve'})
  4. ]

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扩展类使用。
举例:

  1. from rest_framework import mixins
  2. from rest_framework.viewsets import GenericViewSet
  3. from rest_framework.decorators import action
  4. class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
  5. queryset = BookInfo.objects.all()
  6. serializer_class = BookInfoSerializer

url的定义

  1. urlpatterns = [
  2. url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),
  3. url(r'^books/(?P<pk>\d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
  4. ]

3)ModelViewSet

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

4)ReadOnlyModelViewSet

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

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

在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。
添加自定义动作需要使用rest_framework.decorators.action装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:

  • methods: 该action支持的请求方式,列表传递
  • detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)- True 表示使用通过URL获取的主键对应的数据对象
  • False 表示不使用URL获取主键

举例:

  1. from rest_framework import mixins
  2. from rest_framework.viewsets import GenericViewSet
  3. from rest_framework.decorators import action
  4. class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
  5. queryset = BookInfo.objects.all()
  6. serializer_class = BookInfoSerializer
  7. # detail为False 表示不需要处理具体的BookInfo对象
  8. @action(methods=['get'], detail=False)
  9. def latest(self, request):
  10. """
  11. 返回最新的图书信息
  12. """
  13. book = BookInfo.objects.latest('id')
  14. serializer = self.get_serializer(book)
  15. return Response(serializer.data)
  16. # detail为True,表示要处理具体与pk主键对应的BookInfo对象
  17. @action(methods=['put'], detail=True)
  18. def read(self, request, pk):
  19. """
  20. 修改图书的阅读量数据
  21. """
  22. book = self.get_object()
  23. book.bread = request.data.get('read')
  24. book.save()
  25. serializer = self.get_serializer(book)
  26. return Response(serializer.data)

url的定义

  1. urlpatterns = [
  2. url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),
  3. url(r'^books/latest/$', views.BookInfoViewSet.as_view({'get': 'latest'})),
  4. url(r'^books/(?P<pk>\d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
  5. url(r'^books/(?P<pk>\d+)/read/$', views.BookInfoViewSet.as_view({'put': 'read'})),
  6. ]

3. action属性

在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
例如:

  1. def get_serializer_class(self):
  2. if self.action == 'create':
  3. return OrderCommitSerializer
  4. else:
  5. return OrderDataSerializer

4. 视图集的继承关系

视图集的继承关系