二、视图


返回

2.1 普通方式

  • views.py

    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class BookView(APIView):
        """ 全部 """
    
        def get(self, request):
            book_list = Book.objects.all()
            ret = BookSerializer(book_list, many=True)
            return Response(ret.data)
    
        def post(self, request):
            serializer = BookSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            else:
                return Response(serializer.errors)
    
              
    class BookEditView(RetrieveUpdateDestroyAPIView):
        """ 局部 """
    
        def get(self, request, id):
            book_obj = Book.objects.filter(id=id).first()
            ret = BookSerializer(book_obj)
            return Response(ret.data)
    
        def put(self, request, id):
            book_obj = Book.objects.filter(id=id).first()
            serializer = BookSerializer(book_obj, data=request.data, partial=True)  # partial=True,允许部分更新
            if serializer.is_valid():
                serializer.save()
                # return Response(serializer.validated_data)  # validated_data,验证成功的数据
                return Response(serializer.data)  # data 验证成功,并序列化好的数据
            else:
                return Response(serializer.errors)
    
        def delete(self, request, id):
            book_obj = Book.objects.filter(id=id).first()
            book_obj.delete()
            return Response("")
    
    

2.2 代码优化

  • urls.py

    urlpatterns = [
        path('list', BookView.as_view()),
        path('retrieve/<int:id>', BookEditView.as_view()),
    ]
    
    
  • views.py

    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class GenericAPIView(APIView):
        """ 通用类 """
        query_set = None
        serializer_class = None
    
        def get_queryset(self):
            """ 获取model对象 """
            return self.query_set
    
        def get_serializer(self, *args, **kwargs):
            """
            获取serializer对象
            :param args: 实例化所需的参数
            :param kwargs:
            :return: 序列化器对象
            """
            return self.serializer_class(*args, **kwargs)
    
    
    class ListModelMixin(object):
        """ 混合类:全部GET """
    
        def list(self, request):
            queryset = self.get_queryset()
            ret = self.get_serializer(queryset, many=True)
            return Response(ret.data)
    
    
    class CreateModelMixin(object):
        """ 混合类:全部POST """
    
        def create(self, request):
            serializer = self.get_serializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            else:
                return Response(serializer.errors)
    
    
    class RetrieveModelMixin(object):
        """ 混合类:局部GET """
    
        def retrieve(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            ret = self.get_serializer(book_obj)
            return Response(ret.data)
    
    
    class UpdateModelMixin(object):
        """ 混合类:局部PUT """
    
        def update(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            serializer = self.get_serializer(book_obj, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            else:
                return Response(serializer.errors)
    
    
    class DestroyModelMixin(object):
        """ 混合类:局部DELETE """
    
        def destroy(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            book_obj.delete()
            return Response("")
    
    
    class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
        """ 基础继承类 """
        pass
    
    
    class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
        """ 基础继承类 """
        pass
    
    
    class BookView(ListCreateAPIView):
        query_set = Book.objects.all()
        serializer_class = BookSerializer
    
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    
    
    class BookEditView(RetrieveUpdateDestroyAPIView):
        """ 部分更新 """
        query_set = Book.objects.all()
        serializer_class = BookSerializer
    
        def get(self, request, id):
            return self.retrieve(request, id)
    
        def put(self, request, id):
            return self.update(request, id)
    
        def delete(self, request, id):
            return self.destroy(request, id)
    
    

2.3 最终版(利用框架)

  • 框架原生提供了大部分所需的基础类

    from rest_framework import views
    from rest_framework import generics
    from rest_framework import mixins
    from rest_framework import viewsets
    
  • urls.py

    urlpatterns = [
        path('list', BookModelViewSet.as_view({"get": "list", "post": "create"})),
        # 使用框架提供的方法时,id改成pk
        path('retrieve/<int:pk>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    ]
    
    
  • views.py

    class ViewSetMixin(object):
        def as_view(self):
            """
            重写aa_views()方法,以实现按照路由中的参数去匹配
            get-->list、put-->update ...
            """
            pass
    
    
    # rest_framework已经提供了ViewSetMixin
    from rest_framework.viewsets import ViewSetMixin
    
    
    class ModelViewSet(ViewSetMixin, GenericAPIView, ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
        """ 基础继承类 """
        pass
    
    
    # rest_framework也已经提供了ModelViewSet
    from rest_framework.viewsets import ModelViewSet
    
    
    class BookModelViewSet(ModelViewSet):
        """ 最终合并到一个类 """
        # query_set = Book.objects.all()
        queryset = Book.objects.all()  # 使用框架的ModelViewSet,改成queryset
        serializer_class = BookSerializer
    
    
返回