视图集ViewSet

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

list() 提供一组数据

retrieve() 提供单个数据

create() 创建数据

update() 保存数据

destory() 删除数据

ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。

视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。如:

class BookInfoViewSet(viewsets.ViewSet):

    def list(self, request):
        ...

    def retrieve(self, request, pk=None):
        ...

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

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

action属性

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

例如:

def get_serializer_class(self):
    if self.action == 'create':
        return OrderCommitSerializer
    else:
        return OrderDataSerializer

常用视图集父类

1) ViewSet

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

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

python演示代码如下:

from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from book_drf.serializer import BookSerializer
from books.models import BookInfo


class Books(ViewSet):
    # 可以自定义方法名
    def list(self, request):
        # 此处跟django.views获取参数不一样的地方
        # 可以获取类似 ?a=10&b=11 这部分参数
        print(request.query_params)
        # 1、查询所有图书对象
        books = BookInfo.objects.all()
        ser = BookSerializer(books, many=True)
        # 此处跟django.views.View返回不一样
        return Response(ser.data)

    # 可以自定义方法名
    def create(self, request):
        # 此处跟django.views.View
        # 1、获取前端数据
        data = request.data
        # 2、验证数据
        ser = BookSerializer(data=data)
        ser.is_valid()  # 验证方法

        # 3、保存数据
        ser.save()
        # 4、返回结果
        # 此处跟django.views.View返回不一样
        return Response(ser.data)


class BookDRFView(ViewSet):
    """
        获取单一和更新和删除
    """

    # 可以自定义方法名,主要不同点,在路由
    def update(self, request, pk):
        # 此处跟django.views.View
        # 1、获取前端数据
        data = request.data
        # 2、验证数据
        try:
            book = BookInfo.objects.get(id=pk)
        except:
            return Response({'error': '错误信息'}, status=400)
        ser = BookSerializer(book, data=data)
        ser.is_valid()
        # 3、更新数据
        ser.save()
        # 4、返回结果
        # 此处跟django.views.View返回不一样
        return Response(ser.data)

    def lastdata(self, request, pk):
        # 调用的方式 /books_drf/6/lastdata/
        # 路由配置方法 url(r'^books_drf/(?P<pk>\d+)/lastdata/$', viewset_view.BookDRFView.as_view({'get': 'lastdata'})),
        book = BookInfo.objects.get(id=pk)
        ser = BookSerializer(book)
        return Response(ser.data)

    def delete(self, request, pk):
        # 此处跟django.views获取参数不一样的地方
        # 可以获取类似 ?a=10&b=11 这部分参数
        print(pk)
        print(request.query_params)
        try:
            book = BookInfo.objects.get(id=pk)
        except:
            return Response({'error': '错误信息'}, status=400)

        book.is_delete = True
        book.save()
        # 此处跟django.views.View返回不一样
        return Response({})

urls配置路由python代码如下(ViewSet路由配置不同于其它的配置):

from . import viewset_view

urlpatterns = [
    # 配置查询所有图书路由
    url(r'^books_drf/$', viewset_view.Books.as_view({'get': 'list', 'post': 'create'})),
    url(r'^books_drf/(?P<pk>\d+)/$', viewset_view.BookDRFView.as_view({'put': 'update', 'delete': 'delete'})),
    # 匹配与/books_drf/6/lastdata/ 这种形式
    url(r'^books_drf/(?P<pk>\d+)/lastdata/$', viewset_view.BookDRFView.as_view({'get': 'lastdata'})),
]