Your browser does not support the Canvas element.

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视图

       

    

    

posted @ 2018-11-18 16:51  一根小菜  阅读(333)  评论(0编辑  收藏  举报
Your browser does not support the Canvas element.