DRF视图的三次封装
DRF视图相关的类
from rest_framework import views from rest_framework import generics from rest_framework import mixins from rest_framework import viewsets
第一次封装:
1.定义一个通用类
from rest_framework.views import APIView class GenericAPIView(APIView): query_set = None serializer_class = None def get_queryset(self): return self.query_set def get_serializer(self, *args, **kwargs): return self.serializer_class(*args, **kwargs)
2.抽离出get/post/put方法:
class ListModelMixin(object): # list 对应get请求,全部查找 def list(self, request): queryset = self.get_queryset() ret = self.get_serializer(queryset, many=True) return Response(ret.data) class CreateModelMixin(object): # create 对应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): # retrieve 对应get请求(含id),具体查找某一条数据 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): # update 对应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): # destory 对应 DELETE 请求 def destroy(self, request, id): book_obj = self.get_queryset().filter(id=id).first() book_obj.delete() return Response("")
3.在视图中调用
class BookView(GenericAPIView, ListModelMixin, CreateModelMixin): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): book_obj = Book.objects.first() ret = BookSerializer(book_obj) book_list = Book.objects.all() book_list = self.get_queryset() ret = self.get_serializer(book_list, many=True) return Response(ret.data) def post(self, request): print(request.data) serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors)
第二次封装:
整合需要继承的类,然后让视图类来继承这个新的类
class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin): pass class BookView(ListCreateAPIView): query_set = Book.objects.all() serializer_class = BookSerializer def get(self, request): book_obj = Book.objects.first() ret = BookSerializer(book_obj) book_list = Book.objects.all() book_list = self.get_queryset() ret = self.get_serializer(book_list, many=True) return Response(ret.data) def post(self, request): print(request.data) serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors)
第三次封装:
合并视图
想要合并视图,就需要给as_view传参,因此我们需要继承一个能够为as_view传参的类,即ViewSetMixin;
ViewSetMinix将get/post/put等请求与action:list/create/update形成对应关系,通过dispath分发,实现视图的合并;
因此我们需要自定义一个继承ViewSetMixin的CBV:ModelViewSet,并让视图类继承ModelViewSet;
class ModelViewSet(ViewSetMixin, GenericAPIView, ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass class BookModelViewSet(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
在rest_framework中为我们提供了ModelViewSet
from rest_framework.viewsets import ModelViewSet