• DRF之视图组件 三次封装


    1、为什么要进行封装  

      1.1 在处理表的时候,如果有几十张表都需要增删改查查时,如果每一张表都写这些方法,会让代码显得冗余,所以需要将这些方法进行封装,然后不同的表都去继承这写方法。(这是思路)

      1.2 分析需要自定义的内容

        1.2.1 获取到的对象,根据不同的表结构,获取不同的对象内容,比如book_obj , publiser_obj, authors_obj 等等。

            所以 这些   quser_set = None ,到时候根据不同的表去继承。

        1.2.2 序列化器也不同,所以需要serilizer_class = None 

        1.2.3 定义一个通用的类,来让其他类继承

    2、第一次封装

      2.1 定义一个通用的类

    class GenericAPIView(APIView):
        queryset = None
        serializer_class = None
        
        def get_queryset(self):                          # 定义get_queryset方法固定写法get_属性名
            return self.queryset.all()            # 这个self也是BookView的实例化对象
        
        def get_serializer(self, *args, **kwargs):        # 定义一个返回序列化器的类对象的方法,序列化器的参数不同所以用*args 和 **kwargs
            return self.serializer_class(*args, **kwargs)     # 直接返回类的实例化对象
    # 其他类继承她的时候,获取的对象就可以通过self.get_queryset() 或 self.serlializer()来获取

      2.2 将get,post,put,delete等请求方法抽离出来

    class ListModelMixin(object):                                  # list 对应 GET 请求 ,全部查找
        def list(self, request):
            queryset = self.get_queryset()                         # 这个self 也是BookView的实例化对象
            ser_obj = self.get_serializer(queryset, many=True)
            return Response(ser_obj.data)
        
    
    class CreateModelMixin(object):                                # create 对应 POST 请求
        def create(self, request):
            ser_obj = self.get_serializer(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response(ser_obj.validated_data)
            return Response(ser_obj.errors)
        
    
    class RetrieveModelMixin(object):                               # retrieve 对应 GET 请求中的有id 的,单条查找
        def retrieve(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            ser_obj = BookSerializer(book_obj)
            return Response(ser_obj.data)
        
    
    class UpdateModelMixin(object):                    # update 对应 PUT 请求
        def update(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response(ser_obj.validated_data)
            return Response(ser_obj.errors)
        
        
    class DestroyModelMixin(object):                                # destory 对应 DELETE 请求
        def destroy(self, request, id):
            book_obj = self.get_queryset().filter(id=id).first()
            if not book_obj:
                return Response("删除的对象不存在")
            book_obj.delete()
            return Response("")

       2.3、调用

    class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
        
    queryset = Book.objects.all()
        serializer_class = BookSerializer
        def get(self, request): return self.list(request) # 此时的self 是BookView的实例化对象,找list方法,自己没有去父类找,在ListModelMixin找到之后,继续找get_queryset和get_serializer,
                                  # 没有去GenericAPIView找。找到之后乡下执行,返回ser_obj.data
    def post(self, request): return self.create(request)

    3、第二期封装

      3.1二次封装目的就是为了对继承进行了一个整合,方便继承。将BookView中继承的类,让一个新的类去继承,然后自己去继承这个新的类

    # 创建一个新的类ListCreateAPIView,让他继承应该继承的类,然后写个pass,不写任何逻辑,只为让BookView继承
    class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
        pass

      3.2调用 

    class BookView(ListCreateAPIView):        # 继承新类
        queryset = Book.objects.all()
        serializer_class = BookSerializer
    
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)

    4、第三次封装

      4.1 应用理由 ,目的是为了将视图进行合并,用一个视图去解决,在第三次封装前,视图有两个,如图

      4.2 应用场景:重写admin的时候,会用到,一般用不到

      4.3 应用步骤:

        4.3.1 想在url中传参,所以需要重写as_view方法。APIView中的as_view是不允许传参的,会报错。

        4.3.2 自定义一个CBV ,ModelViewSet,让他继承ViewSetMixin,因为ViewSetMinix类中,重写了as_view方法,允许传参了

            ViewSetMinix把get/post/put等请求 对应成了 list/create/update 这种对应关系,所以在dispath分发的时候,就变成了get ===> self.list

        

        4.3.3 在views中重新写一个CBV,BookModelView 继承ModelViewSet

        

        4.3.4 在urls中给路由传参数,写好对应关系,现在就是一个BookModelView视图

           

        

        

  • 相关阅读:
    讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)
    Sagit.Framework For IOS 开发框架入门教程4:注册页布局-被消灭的变量
    Sagit.Framework For IOS 开发框架入门教程3:Start引导页及框架布局和隐藏事件的内幕
    Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页
    Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置
    CYQ.Data 正式支持 DotNET Core 版本发布
    IT连创业系列:App产品上线后,运营怎么搞?(中)
    IT连创业系列:App产品上线后,运营怎么搞?(上)
    分享:苹果APP更新上架被拒的另一种理由(Safety
    IT连创业系列:说说苹果商店AppStore上架App应用前后遇到的那些神坑
  • 原文地址:https://www.cnblogs.com/wf123/p/9978409.html
Copyright © 2020-2023  润新知