• rest-framework之视图


    路由

     url(r'^publish/$', views.PublishView.as_view()),
     url(r'^publish/(?P<pk>d+)/$', views.PublishDetailView.as_view()),

     基本视图

    from rest_framework.response import Response
    from  rest_framework import serializers
    from app01 import models
    from rest_framework.views import  APIView
    # Create your views here.
    class PublishSerializers(serializers.ModelSerializer):
        class Meta:
            model=models.Publish
            fields='__all__'
    #基本视图
    class PublishView(APIView):
    
        def get(self, request):
            publish_list = models.Publish.objects.all()
            bs = PublishSerializers(publish_list, many=True)
            # 序列化数据
    
            return Response(bs.data)
    
        def post(self, request):
            # 添加一条数据
            print(request.data)
    
            bs=PublishSerializers(data=request.data)
            if bs.is_valid():
                bs.save()  # 生成记录
                return Response(bs.data)
            else:
    
                return Response(bs.errors)
    
    class PublishDetailView(APIView):
        def get(self,request,pk):
            publish_obj=models.Publish.objects.filter(pk=pk).first()
            bs=PublishSerializers(publish_obj,many=False)
            return Response(bs.data)
        def put(self,request,pk):
            publish_obj = models.Publish.objects.filter(pk=pk).first()
    
            bs=PublishSerializers(data=request.data,instance=publish_obj)
            if bs.is_valid():
                bs.save() # update
                return Response(bs.data)
            else:
                return Response(bs.errors)
        def delete(self,request,pk):
            models.Publish.objects.filter(pk=pk).delete()
    
            return Response("")
    基本视图

    minins类和generice类编写视图

    from app01 import models
    from rest_framework import serializers
    # Create your views here.
    class PublishSerializers(serializers.ModelSerializer):
        class Meta:
            model = models.Publish
            fields ='__all__'
    #基于mixins来封装视图
    from rest_framework.mixins import CreateModelMixin,ListModelMixin,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin
    from rest_framework.generics import GenericAPIView
    class PublishView(CreateModelMixin,ListModelMixin,GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        def post(self,request,*args,**kwargs):
            return self.create(request,*args,**kwargs)
        def get(self,request,*args,**kwargs):
            return self.list(request,*args,**kwargs)
    
    class PublishDetailView(RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin,GenericAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
        def get(self,request,*args,**kwargs):
            return self.retrieve(request,*args,**kwargs)
        def put(self,request,*args,**kwargs):
            return self.update(request,*args,**kwargs)
        def delete(self,request,*args,**kwargs):
            return self.destroy(request,*args,**kwargs)

    源码分析 

    分析这两个到底是啥东西?

    serializer_class

    这两个东西是在GenericAPIView里面

    继续往下看,,然后发现create方法里面用到了这个方法

    这里get_serializer是序列化的类

    本质就是调了再点进去看看直接return了serializer_class,然而这里是None,所以我们需要在自己写的类里面把这两个东西配置好。然后就把PublishSerializers传过去,

    querset

    然后看一下querset,querset是list的时候用的这里不能直接ctrl点进去看,自己没有,ListModeMixin也没有,就应该在GenericAPIView里面,

     获取此视图的项列表。这必须是一个可迭代的,并且可能是一个queryset。一般情况下都会加.all,免得耗费资源

    第二种写法

    from rest_framework.generics import CreateAPIView,ListCreateAPIView,DestroyAPIView,RetrieveUpdateDestroyAPIView
    class PublishView(ListCreateAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers
    
    class PublishDetailView(RetrieveUpdateDestroyAPIView):
        queryset = models.Publish.objects.all()
        serializer_class = PublishSerializers

    源码部分

    ListCreateAPIView里面继承了ListModelMixin,CreateModelMixin,GenericAPIView里面封装了get和list方法

    RetrieveUpdateDestroyAPIView里面也是一样封装了get,put/patch,delete方法

     

    第三种写法

    五个接口写在一个类中

    路由

    url(r'^publish/$', views.PublishView.as_view({'get':'list','post':'create'})),
    url(r'^publish/(?P<pk>d+)/$', views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
    from rest_framework.viewsets import ModelViewSet
    class PublishView(ModelViewSet):
        queryset=models.Publish.objects.all()
        serializer_class=PublishSerializers

     源码部分

    继承了五个了方法的类

    注意这里的GenericViewSet不是GenericAPIView,来我们点进去看一下

    发现里面没有写,这里唯一没见过的就是ViewSetMixin,点进去看一下

    这里的意思是

    这就是魔法。重写' .as_view() ',使其接受' actions '关键字,该关键字将HTTP方法绑定到资源上的操作。例如,要创建一个将“GET”和“POST”方法绑定到“list”和“create”操作的具体视图……

    这里面的as_view跟原来的as_view多了一个actions的参数

    路由里面是字典

    所以这里的actions就是路由配置的字典

    如果继承了ViewSetMixin就必须穿actions参数否则就抛异常

    重点来了

    这里重写了view方法,这里把收到的字典key和value取出来,

    通过反射去里面找list,然后把list的内存地址给了get,这就是为啥执行了get请求执行的是list方法 ,这样一个视图类就可以相应很多方法,只要有映射关系

    as_view方法内部执行效果
    通过反射的取值跟赋值,完成映射,根据请求方式执行对应的方法(比如:get请求执行list方法,在路由中配置{get:liste})

    ViewSetMixin重写了as_view方法

    from rest_framework.viewsets import  ViewSetMixin
    from rest_framework.views import  APIView
    # ViewSetMixin 重写了as_view方法
    class Test(ViewSetMixin,APIView):
    
        def aaa(self,request):
            return Response()

    这里没有继承View和APIView,所以视图类中还要继承APIView,

    但是有先后顺序,因为APIView里面也有个as_view,就会先调用这个,所以放在后面

    路由配置就要改了 比如

     url(r'^aa/$', views.PublishView.as_view({'get': 'aaa'})),

    这样get请求来了就走aaa这个方法

  • 相关阅读:
    Go语言核心36讲(Go语言实战与应用九)学习笔记
    Go语言核心36讲(Go语言实战与应用六)学习笔记
    Go语言核心36讲(Go语言实战与应用二十一)学习笔记
    Go语言核心36讲(Go语言实战与应用十二)学习笔记
    Go语言核心36讲(Go语言实战与应用七)学习笔记
    Go语言核心36讲(Go语言实战与应用二十)学习笔记
    Go语言核心36讲(Go语言实战与应用二十四)学习笔记
    .NET 云原生架构师训练营(对象过程建模)学习笔记
    Go语言核心36讲(Go语言实战与应用二十二)学习笔记
    .NET 云原生架构师训练营(ASP .NET Core 整体概念推演)学习笔记
  • 原文地址:https://www.cnblogs.com/zhengyuli/p/11129847.html
Copyright © 2020-2023  润新知