(day74)视图家族(视图基类、视图工具类、工具视图类、视图集)、十大接口和路由层补充

一、views:视图基类

(一)APIView(回顾)

  1. 继承View类
  2. 重写as_view
  3. 重写dispatch

(二)GenericAPIView

  1. 继承APIView
  2. get_queryset方法:配置queryset类属性,提供视图类相关的Models
    • queryset属性:获取queryset对象,最后要使用.all()方法转换成queryset对象,防止内部获取的为manage对象而出错
  3. get_serializer方法:配置serilaizer_class属性,提供视图类相关的序列化对象
    • serializer_class属性:获取序列化对象,不能加括号(否则就是实例化类)
  4. get_object方法:在get_queryset基础上,配置lookup_url_kwarg属性,提供视图类相关的具体Model
    • lookup_url_kwarg属性:默认为pk,url中有名分组名如果不为pk,需要重新定义

总结:GenericAPIView就是在APIView基础上额外提供了三个方法,三个类属性

from rest_framework.generic import GenericAPIView
class CarGenericAPIView(GenericAPIView):
    # models.Car.object不是queryset对象,是manage对象,所以资源一定要在外部自己.all()
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    # lookup_url_kwargs = 'pk'
    
    # 群查
    def get(self,request,*args,**kwargs):
        # 获取queryset对象
        car_query = self.get_queryset()
        #获取序列化对象
        car_ser = self.get_serialzier(car_query,many=True)
        return APIResponse(results = car_ser.data)
    
    # 单查
    def get(self,request,*args,**kwargs):
        car_obj = self.get_object()
        car_ser = self.get_serialzier(car_obj)
        return APIResponse(results = car_ser.data)
        

二、mixins:视图工具类

  1. 要配合GenericAPIView类使用,将单查、群查、单增、整体单改、局部单改、单删六个接口操作封装成retrieve、list、create、update、partial_update、destroy六个方法
    • 六个方法的实现体,调用的方法就是GenericAPIView提供的,所以要配合其使用

(一)CreateModelMixin

  • 创建视图工具类,提供了create方法快速实现数据库单增操作,成功返回201状态码,数据验证失败返回400
from rest_framework.mixins import CreateModelMixin
from rest_framework.generic import GenericAPIView

class CarCreateGenericAPIView(CreateModelMixin,GenericAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    
    # 单增
    def post(self,request,*args,**kwargs):
        return self.create(request,*args,**kwargs)

(二)ListModelMixin

  1. 群查视图工具类,提供了list方法快速实现群查操作,返回200状态码
  2. list方法也会对数据进行过滤和分页
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import ListModelMixin

class CarListGenericAPIView(ListModelMixin,GenericAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    
    # 群查
    def get(self,request,*args,**kwargs):
        return self.list(request,*args,**kwargs)

(三)RetrieveModelMixin

  • 单查视图工具类,提供retrieve方法快速实现单查操作,存在返回202,否则404
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin

class CarRetrieveGenericAPIView(RetrieveModelMixin,GenericAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    
    # 单查
    def get(self,request,*args,**kwargs):
        return self.retrieve(request,*args,**kwargs)

(四)UpdateModelMixin

  1. update方法:可以快速实现一个数据对象的整体单改操作
  2. partial_update方法:可以快速实现一个数据对象的局部单改操作
  3. 修改视图工具类,成功返回200,数据校验失败返回400错误
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import UpdateModelMixin

class CarUpdateGenericAPIView(UpdateModelMixin,GenericAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    
    # 整体单改
    def put(self,request,*args,**kwargs):
        return self.update(request,*args,**kwargs)
    
    # 局部单改
    def patch(self,request,*args,**kwargs):
        return self.partial_update(request,*args,**kwargs)

(五)DestroyModelMixin

  1. 删除视图工具类,提供了destroy方法快速实现一个数据对象的删除操作,成功返回204,不存在返回404
  2. 实际开发中,使用is_delete字段标记数据对象的删除,因此并不会用到该方法,需要重写该方法。
from rest_framework.generic import GenericAPIView
from rest_framework.mixins import DestroyModelMixin

class CarDeleteGenericAPIView(DestroyModelMixin,GenericAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()  
    serialzier_class = serializers.CarModelSerializer
    
    # 单删
    def put(self,request,*args,**kwargs):
        return self.delete(request,*args,**kwargs)

三、generics:工具视图类

  1. 封装了不同个数和不同中的mixins与GenericAPIView的组合
  2. 不同的组合可以实现对应的get、post、put、patch、delete方法
  3. 使用时,只需配置三个属性即可:queryset、serializer_class和lookup_url_kwarg
from mrest_freamework.generics import RetrieveAPIView,ListAPIView
# (三)单查接口
class CarRetrieveAPIView(RetrieveAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()
    serialzier_class = serializers.CarModelSerializer
    # lookup_url_kwarg = 'pk'

# (二)群查接口    
class CarListAPIView(ListAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()
    serialzier_class = serializers.CarModelSerializer 
    
# (九)单查、整体单改、局部单改、单删接口
from mrest_freamework.generics import RetrieveUpdateDestroyAPIView
class CarRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
    queryset = models.Car.object.filter(is_delete=False).all()
    serialzier_class = serializers.CarModelSerializer    

(一)CreateAPIView

  1. 单增
  2. 封装了post方法
  3. 继承:CreateModelMixin,GenericAPIView

(二)ListAPIView

  1. 群查
  2. 封装了get方法
  3. 继承:ListModelMixin,GenericAPIView

(三)RetrieveAPIView

  1. 单查
  2. 封装了get方法
  3. 继承:RetrieveModelMixin,GenericAPIView

(四)DestoryAPIView

  1. 单删
  2. 封装了delete方法
  3. 继承:DestroyModelMixin,GenericAPIView

(五)UpdateAPIView

  1. 整体单改和局部单改
  2. 封装了put方法和patch方法
  3. 继承:UpdateModelMixin,GenericAPIView

(六)ListCreateAPIView

  1. 群查、单增
  2. 封装了get方法和post
  3. 继承:ListModelMixin,CreateModelMixin,GenericAPIView

(七)RetrieveUpdateAPIView

  1. 单查、整体单改、局部单改
  2. 封装了get、put、patch方法
  3. 继承:RetrieveModelMixin,UpdateModelMixin,GenericAPIView

(八)RetrieveDestroyAPIView

  1. 单查、单删
  2. 封装了get方法和delete方法
  3. 继承:RetrieveModelMixin,DestroyModelMixin,GenericAPIView

(九)RetrieveUpdateDestroyAPIView

  1. 单查、整体单改、局部单改、单删
  2. 封装了get、put、patch、delete方法
  3. 继承:RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView

四、viewsets:视图集

(一)工具类:ViewSetMixin

  1. 不继承任何类,重写了as_view方法,相比APIView的as_view方法,额外添加了一个参数actions
  2. actions属性:接收as_view({'get':'list'})中的{'get':'list'},从而将get请求映射到视图类的list函数
  3. 其他的视图集类都继承了ViewSetMixin类

(1)ViewSet

  1. 继承了ViewSetMixinGenericAPIView
  2. 不提供get、put等方法,需要手动定义,应用于一些特定的发送post请求但是不用操作数据库的接口,比如:登录接口和短信验证码接口

(2)GenericViewSet

  1. 继承了ViewSetMixinGenericAPIView
  2. 提供了get、put等方法,该分支严格满足资源接口

(三)视图集子类

(1)ReadOnlyModelViewSet

  1. 继承自GenericViewSet,同时包括了RetrieveModelMixin、ListModelMixin
  2. 可以完成单查、群查两个接口
  3. 要在urls文件中配置as_view设置映射关系(actions接收)
# urls.py
urlpatterns=[
        url(r'^v6/cars/$', views.CarReadOnlyAPIView.as_view({'get': 'list'})),
    url(r'^v6/cars/(?P<pk>\d+)/$', views.CarReadOnlyAPIView.as_view({'get': 'retrieve'})),
]
from rest_framework.viewsets import ReadOnlyModelViewSet
class CarReadOnlyAPIView(ReadOnlyModelViewSett):
    queryset = models.Car.objects.filter(is_delete=False).all()
    serializer_class = serializers.CarModelSerializer

(2)ModelViewSet

  1. 继承自GenericViewSet,同时包括了CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin、ListModelMixin
  2. 可以完成单增、单查、整体单改、局部单改、单删、群查六个接口
  3. 要在urls文件中配置as_view设置映射关系(actions接收)
# urls.py
urlpatterns=[
    url(r'^v7/cars/$', views.CarModelViewSet.as_view({
        'get': 'list',
        'post': 'create',
    })),
    url(r'^v7/cars/(?P<pk>\d+)/$', views.CarModelViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'destroy',
    })),
]
# views.py
from rest_framework.viewsets import ViewSetsMixin,GenericViewSet,ViewSet
class CarView(RetrieveModelMixin,ListModelMixin,GenericViewSet):
     queryset = models.Car.object.filter(is_delete=False).all()
    serialzier_class = serializers.CarModelSerializer 

五、十大接口与路由层补充

(一)十大接口

  1. 通过重写继承解决响应结果没有数据状态码和状态信息的问题
  2. 通过重写delete方法解决根据is_delete字段值判断删除的问题
  3. 通过自定义和重写方法来解决没有群增、整体群改、局部群改、群删四个接口的问题
# urls.py
urlpatterns=[
    url(r'^v7/cars/$', views.CarModelViewSet.as_view({
        'get': 'list',
        'post': 'create',
        'put': 'many_update',
        'patch': 'many_partial_update',
        'delete': 'many_destroy',
    })),
    url(r'^v7/cars/(?P<pk>\d+)/$', views.CarModelViewSet.as_view({
        'get': 'retrieve',
        'put': 'update',
        'patch': 'partial_update',
        'delete': 'destroy',
    })),
]
# 十大接口
class CarModelViewSet(ModelViewSet):
    queryset = models.Car.object.filter(is_delete=False).all()
    serialzier_class = serializers.CarModelSerializer 
    
    # 1. 通过重写继承解决响应结果没有数据状态码和状态信息的问题
    def list(self,request,*args,**kwargs):
        response = super().list(request,*args,**kwargs)
        return APIRsponse(results = response.data)
    
    # 2. 通过重写delete方法解决根据is_delete字段值判断删除的问题
    def destroy(self,request,*args,**kwargs):
        car_obj = self.get_object()  # 如果获取失败,将会被异常模块捕捉
        car_obj.is_delete = True
        car_obj.save()
        return APIView(msg='删除成功')
    
    # 3.1 群删问题(定义many_destroy方法)
    def many_destroy(self,request,*args,**kwargs):
        ###自己补充
       
    # 3.2 整体群改问题(定义many_destroy方法)
    def many_update(self,request,*args,**kwargs):
        ###自己补充
       
    # 3.3 局部群改问题(定义many_detroy方法)
    def many_partial_update(self,request,*args,**kwargs):
        ###自己补充
       
    # 3.4 群增(重写create方法)
    def create(self,request,*args,**kwargs):
        if isinstance(reqeust.data,list):
            car_ser = self.get_serialzier(data=reqeust.data,many=True)
            car_ser.is_valid(raise_exception=True)
            car_obj = car_ser.save()
            return APIView(msg='群增成功',results=self.get_serialzier(car_obj,many=True).data )
           
        return super().create(request,*args,**kwargs)

(二)路由层SimpleRouter类

该方法由drf提供

# urls.py
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('v7/cars', views.CarModelViewSet, basename='car')

urlpatterns = [url(r'', include(router.urls))]
# urlpatterns.extend(router.urls)

猜你喜欢

转载自www.cnblogs.com/wick2019/p/12122127.html