• drf视图


    不使用drf视图

    #在下面的这些代码中,存在很多代码重复
    from rest_framework.views import APIView
    from app01.models import *
    from app01.mySer import *
    from django.http import JsonResponse
    
    class PublishView(APIView):
    
        def get(self, request):     #获取所有数据
            publish_list = Publish.objects.all()
            bs = PublishSerializers(publish_list, many=True)    #PublishSerializers自己写的序列化
    
            return JsonResponse(bs.data,safe=False)
    
        def post(self, request):     #添加纪录
            # 添加一条数据
            print(request.data)
    
            bs = PublishSerializers(data=request.data)
            if bs.is_valid():
                bs.save()  # 生成记录
                return JsonResponse(bs.data,safe=False)
            else:
    
                return JsonResponse(bs.errors,safe=False)
    
    
    class PublishDetailView(APIView):
        def get(self, request, pk):      #获取单条数据
            publish_obj = Publish.objects.filter(pk=pk).first()
            bs = PublishSerializers(publish_obj, many=False)
            return JsonResponse(bs.data,safe=False)
    
        def put(self, request, pk):    #修改单条
            publish_obj = Publish.objects.filter(pk=pk).first()
    
            bs = PublishSerializers(data=request.data, instance=publish_obj)
            if bs.is_valid():
                bs.save()  # update
                return JsonResponse(bs.data)
            else:
                return JsonResponse(bs.errors)
     
        def delete(self, request, pk):  #删除一条数据
            Publish.objects.filter(pk=pk).delete()
    
            return JsonResponse("")
    View Code

    还是不使用drf,但进行了封装

    #自己写两个类,把重复代码抽出来
    class List:    #列表,拿多条
        #把获取多条的get抽过来
        def list(self):              
            publish_list = Publish.objects.all()
            bs = PublishSerializers(publish_list, many=True)  # PublishSerializers自己写的序列化
    
            return JsonResponse(bs.data, safe=False)
    
    
    class Create:
      #把post方法抽过来
        def create(self,request):      
            bs = PublishSerializers(data=request.data)
            if bs.is_valid():
                bs.save()  # 生成记录
                return JsonResponse(bs.data, safe=False)
            else:
                return JsonResponse(bs.errors, safe=False)
    
    ------------------------------------------------------------
    #使用的时候
    class PublishView(APIView,List,Create):
    
        def get(self, request):  # 获取所有数据
            return self.list(request)      #当请求来到这时,在当前找不到list方法,然后去父类找,执行,并拿到结果
    
        def post(self, request):
            return self.create(request)#同理,请求来了,去父类中找create方法
    
    ---------------------------------------------------
    #但是
    #上面这种方式只能对应Publish表,PublishSerializers序列化组件,写死了
    class BookhView(APIView, List, Create)    
                                              #
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    不够精简的封装
    #把写死的地方,通过传值写活
    
    class List:    #列表,拿多条
        def list(self):    #把获取多条的get抽过来
            # publish_list = Publish.objects.all()     #原来的方式
            # bs = PublishSerializers(publish_list, many=True
    
            queryset = self.queryset               #把原本写死的东西写活
            bs = self.serializers(queryset, many=True)  #把原本写死的东西写活
    
            return JsonResponse(bs.data, safe=False)
    
    class Create:
        def create(self,request):      #把post方法抽过来
            print(request.data)
            # bs = PublishSerializers(data=request.data)
            bs = self.serializers(data=request.data)         #把原本写死的东西写活
            if bs.is_valid():
                bs.save()  # 生成记录
                return JsonResponse(bs.data, safe=False)
            else:
                return JsonResponse(bs.errors, safe=False)
    
    -------------------------------------------
    #使用
    class PublishView(APIView,List,Create):      #前边自己写的两个类,是怎么处理,一定要与这里的怎么用区分开,条理清晰
        queryset= Publish.objects.all()         #需要用哪个模型表,就传给queryset
        serializers=PublishSerializers          #需要用哪个序列化组件,就把谁赋给serializers
        def get(self, request):  # 获取所有数据
            return self.list(request)      #当请求来到这时,在当前找不到list方法,然后去父类找,执行,并拿到结果
    
        def post(self, request):
                return self.create(request)#同理,请求来了,去父类中找create方法
    
    
    class BookhView(APIView, List, Create)     #此时就比较方便了,再来多少都行,只需要把模型表
        queryset= Book.objects.all()         #需要用哪个模型表,就传给queryset
        serializers=BookSerializers          #需要用哪个序列化组件,就把谁赋给serializers
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    升级版封装

    使用drf封装的类

    先看源码(拿两个典型的,其他的类似)

    #GenericAPIView它继承了APIView,只不过添加了一些方法
    其他几个类要基于它使用,
    class GenericAPIView(views.APIView):
        queryset = None
        serializer_class = None
    
        lookup_field = 'pk'
        lookup_url_kwarg = None
    
        filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
    
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
    
        def get_queryset(self):
        def get_object(self):
        def get_serializer(self, *args, **kwargs):
        def get_serializer_class(self)     
        def get_serializer_context(self)
        def filter_queryset(self, queryset)
    GenericAPIView源码
    class ListModelMixin(object):
    
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())  #类似于自己写的queryset 
    
            page = self.paginate_queryset(queryset)    #分页相关
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    
    
    queryset     #这些都需要去GenericAPIView中
    get_queryset
    filter_queryset
    ListModelMixin源码

    使用

    #GenericAPIView继承了APIView,只不过添加了几个方法
    
    #拿多个
    class PublishView(GenericAPIView,ListModelMixin,CreateModelMixin):
        queryset= Publish.objects.all()
        serializer_class=PublishSerializers
        def get(self, request):
            return self.list(request)   
    
    #请求来到这里,list方法,自己,没有,去父类,在ListModelMixin中找到,父类中需要的
    filter_queryset,paginate_queryset,get_serializer先来自己这找,自己这没有,去父类中,在GenericAPIView中找到
    
        def post(self, request):      #添加用CreateModelMixin
            return self.create(request)   #同样道理,create去父类中找,父类中需要的其他参数,去另外父类中找
    
    
    ---------------------------------------------------------
    #拿一个的方法,道理同上
    from rest_framework.mixins import ListModelMixin,RetrieveModelMixin,RetrieveModelMixin,DestroyModelMixin
    from rest_framework.generics import GenericAPIView
    
    
    class PublishDetailView(APIView):
        queryset= Publish.objects.all()
        serializer_class=PublishSerializers
        def get(self, request,pk):               #RetrieveModelMixin
            return self.retrieve(self, request, pk)
    
    
        def post(self, request,pk):            #RetrieveModelMixin
            return self.update(request,pk)
    
    
        def delete(self, request, pk):       #DestroyModelMixin
            return self.destroy(request,pk)
    
    
    
    
    ------------------------------------------
    #这种方法仍然存在重复代码,取多个,取一个都要指定
        queryset= Publish.objects.all()
        serializer_class=PublishSerializers
    View Code

    使用drf升级版(最终版)

    # 上面发现仍有重复代码
    # queryset = Publish.objects.all()
    # serializers = PublishSerializers
    from rest_framework.viewsets import ModelViewSet
    class PublishDetailView(ModelViewSet):    #只需要写这一个,5个接口都有了
        queryset= Publish.objects.all()
        serializer_class=PublishSerializers
    
    
    #不过路由需要传参
        url(r'^books/$', views.Book.as_view({'get': 'list', 'post': 'create'})),
        url(r'^books/(?P<pk>d+)/$',views.Book.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),

     这种情况不建议使用,一般自己写类,继承魔法类,自己在类中实现功能

     

    #1、ModelViewSet
    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,           #前四个已经了解
                       GenericViewSet):      #重点读这个源码
    
    
    2、#来到GenericViewSet
    class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    
        pass     #源码的pass
    #它继承了ViewSetMixin
    
    
    
    
    #3、来看ViewSetMixin
    #url(r'^books/$', views.Book.as_view({'get': 'list', 'post': 'create'})),
    #url(r'^books/(?P<pk>d+)/$',views.Book.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
    
    class ViewSetMixin(object):    #路由的参数给actions
        def as_view(cls, actions=None, **initkwargs):
    
            def view(request, *args, **kwargs):  #重写了view方法
                  #{'get': 'list', 'post': 'create'}
                 #如果method=get  ,action = list
                for method, action in actions.items():    #解压取值
                    #handler 就是list的内存地址
                    handler = getattr(self, action)
                     #把list的内存地址,赋值给了get,    
                    setattr(self, method, handler)
    那么如果是{'get': 'retrieve'},,直接把retrieve赋值给get
    ViewSetMixin魔法类
    #可以实现在一个类中,路由地址不一样
    
    
    
    
    from rest_framework.viewsets import ViewSetMixin
    #注意前后顺序,ViewSetMixin一定放在前边,为了执行它的as_view方法
    class TestAll(ViewSetMixin,APIView):
        def text1(self,request):
            return HttpResponse('text1')
    
        def text2(self,request):
            return HttpResponse('text2')
    
        def text3(self,request):
            return HttpResponse('text3')
    
        def text4(self,request):
            return HttpResponse('text4')
    
    
    ------------------------------------------------
    urls
        url(r'^text1/$', views.TestAll.as_view({'get': 'tet1'})),
        url(r'^text1/$', views.TestAll.as_view({'get': 'tet2'})),
        url(r'^text1/$', views.TestAll.as_view({'get': 'tet3'})),
        url(r'^text1/$', views.TestAll.as_view({'get': 'tet4'})),
    魔法类用法
  • 相关阅读:
    leetcode 54. 螺旋矩阵 js高效实现
    leetcode 141. 环形链表 js 实现
    通过 BFC 实现页面布局
    leetcode 1351. 统计有序矩阵中的负数 js实现
    js 实现元素拖拽
    如何在 chrome控制台快速获取某段 html?
    leetcode 160. 相交链表 js 实现
    leetcode 70. 爬楼梯 js实现
    nodejs中事件循环中的执行顺序
    leetcode 300. 最长递增子序列 js 动态规划实现
  • 原文地址:https://www.cnblogs.com/pdun/p/11257059.html
Copyright © 2020-2023  润新知