• Django-DRF-视图的演变


     

     

    版本一(基于类视图APIView类)

    views.py:

    APIView是继承的Django View视图的。

     1 from .serializers import UserSerializers    #导入当前目录配置好的序列化器                 
     2 from .models import User                    #导入数据库
     3 from rest_framework.views import APIView    #导入APIView 
     4 from rest_framework.response import Response  #该模块返回json数据
     5 from rest_framework import status           #内置状态码模块
     6 
     7 class UserAPIView(APIView):          #查看所有及添加数据视图
     8     def get(self,request):    
     9         users = User.objects.all()          #获取数据库里所有数据
    10         ser = UserSerializers(instance=users,many=True) #进行序列化操作,指定更多集合对象
    11         return Response(ser.data,status=200)#返回成功数据
    12 
    13     def post(self,request):          #添加数据
    14         ser = UserSerializers(data=request.data)#接收前台传输数据
    15         if ser.is_valid():                  #判断书否合法raise_exception=True加次参数表示不合法抛出异常,默认false
    16             ser.save()                      #保存
    17             return Response(ser.data,status=200)
    18         return Response(ser.errors)         #返回错误信息
    19 
    20 class UserSingleView(APIView):       #单条查询,改,删除视图
    21     def get(self,request,pk):               
    22         user = User.objects.get(id=pk)      #查询单条集合对象
    23         ser = UserSerializers(instance=user)#序列化数据
    24         return Response(ser.data)
    25 
    26     def put(self,request,pk):        #修改
    27         user = User.objects.get(pk=pk)
    28         ser = UserSerializers(instance=user,data=request.data)  #注意指定参数
    29         if ser.is_valid():
    30             ser.save()
    31             return Response(ser.data,status=200)
    32         return Response(ser.errors)
    33 
    34     def delete(self,request,pk):     #删除操作
    35         User.objects.get(pk=pk).delete()   
    36         return Response(status=status.HTTP_200_OK)
    代码说明:
    1. 使用类视图,定义两个类并继承APIView类视图;
    2. 在类视图里编写:增删改查方法,通过HttpResponse返回状态。

    serializers.py

    
    

    from rest_framework import serializers #导入序列

    from .models import User #导入表

    class UserSerializers(serializers.Serializer):#注意继承的类
        nick_name = serializers.CharField(max_length=20,required=True)    #required=True设置必须验证
        gender = serializers.BooleanField(default=0,required=False)
       def create(self, validated_data):         #创建数据的操作
            return User.objects.create(**validated_data)
    
       def update(self, instance, validated_data):#修改数据的操作
        
    instance接收的是数据库查询的单个对象,validated_data为前端传输的数据
    instance.nick_name
    = validated_data.get('nick_name',instance.nick_name) instance.gender = validated_data.get('gender',instance.gender) instance.save()          #取出值每个字段进行保存 return instance

    版本二(使用混合 mixins)

    继承generics和mixins里的方法,称之为“混合”

    views.py:

     1 from rest_framework import mixins, generics  # 导入相应模块
     2 # mixins就是一个类,只不过这个类里定义了很多操作数据的方法
     3 from .serializers import UserModelSerializer
     4 class UserGenericAPIview(generics.GenericAPIView,mixins.ListModelMixin,mixins.CreateModelMixin):
     5     queryset = UserInfo.objects.all()      # queryset指定集合数据是从哪个数据库来
     6     serializer_class =UserModelSerializer  # serializer_class配置序列化器类UserModelSerializer
     7 
     8     # 调用mixins.ListModelMixin类的list()方法
     9     def get(self,request):
    10         return self.list(request)
    11 
    12     # 调用mixins.CreateModelMixin类的create()方法 
    13     def post(self,request):
    14         return self.create(request)
    15 
    16 class UserGenericSingleView(generics.GenericAPIView,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin):
    17     queryset = UserInfo.objects.all()
    18     serializer_class = UserModelSerializer
    19 
    20     # 调用mixins.RetrieveModelMixin类的retrieve()方法
    21     def get(self,request,pk):  #检索
    22         return self.retrieve(request)
    23 
    24     # 调用mixins.UpdateModelMixin类的update()方法
    25     def put(self,request,pk):  #修改
    26         return self.update(request)
    27 
    28     # 调用mixins.DestroyModelMixin类的destroy()方法
    29     def delete(self,request,pk):  #破坏
    30         return self.destroy(request)
    代码说明:
    1. 为什么要继承mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin等这一堆方法呢?
    答:比如我们自定义写了delete方法,而这个方法会自动、只能的去调用mixins.DestroyModelMixin这个类里面的动作。

    serializers,py

    1 from rest_framework import serializers
    2 from .models import UserInfo
    3 
    4 class UserModelSerializer(serializers.ModelSerializer):
    5     class Meta:
    6         #配置model为UserInfo
    7         model = UserInfo  
    8         fields = "__all__"   #fields配置要序列化的字段,"__all__"表示所有的字段都序列化

    在上个版本中,queryset和serializer属性都是通过自己声明去使用的;

    这个版本继承使用混合继承了generics,通过查看generics源码发现如下:

    class GenericAPIView(views.APIView):
    ···
        queryset = None
        serializer_class = None
    ···

    版本三(使用混合高级版)

    views.py:

    1 from rest_framework import generics
    2 
    3 class UserListAPIView(generics.ListCreateAPIView):
    4     queryset = UserInfo.objects.all()
    5     serializer_class = UserModelSerializer
    6 
    7 class UserSingleView(generics.RetrieveUpdateDestroyAPIView):
    8     queryset = UserInfo.objects.all()
    9     serializer_class = UserModelSerializer

    这几行代码搞定上面所有功能,只需要传入queryset和serializer即可,这什么原理呢?

    1、第二版本中,我们继承了generics.GenericAPIView类视图,自己写了两个get和post方法对吧,那generics的另一个方法把这两个事情也干了,我们只需要继承即可。
    2、对的,这个方法就是generics.ListCreateAPIView,我们且看看它的源码,你就明白了
    class ListCreateAPIView(mixins.ListModelMixin,
                            mixins.CreateModelMixin,
                            GenericAPIView):       
        """
        Concrete view for listing a queryset or creating a model instance.
        """
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)

    版本四(视图集 ViewSet

    views.py:

     1 from rest_framework import viewsets,mixins
     2 class GennericViewsSet(viewsets.GenericViewSet,
     3                        mixins.CreateModelMixin,
     4                        mixins.ListModelMixin,
     5                        mixins.RetrieveModelMixin,
     6                        mixins.UpdateModelMixin,
     7                        mixins.DestroyModelMixin
     8                        ):
     9     queryset = UserInfo.objects.all()
    10     serializer_class = Userserializer

    这个版本views里就写了一个类视图,之前的所有版本都是写一个List和一个Detail视图的,

    这个类 继承了viewsets.GenericViewSet,其他的方法都是mixins的viewsets

    GenericViewSet继承了ViewSetMixin方法,从ViewSetMixin的源码里能看到可以改写as_view的信息,来达到定制路由的效果

    class ViewSetMixin(object):
        @classonlymethod
        def as_view(cls, actions=None, **initkwargs):
          ······
            if not actions:
                raise TypeError("The `actions` argument must be provided when "
                                "calling `.as_view()` on a ViewSet. For example "
                                "`.as_view({'get': 'list'})`")

    urls.py:

    1 from django.conf.urls import url
    2 from . import views
    3 
    4 urlpatterns = [
    5     url(r'^$',views.GennericViewsSet.as_view({'get':'list',"post": "create"})),   #注意这里的写法
    6     url(r'^users/(?P<pk>d+)/$',views.GennericViewsSet.as_view({'get':'retrieve','put':'update','delete':'destroy'}))
    7 ]

    版本五 (终极大法:写项目选用此法)

    views.py:

    1 from rest_framework.viewsets import ModelViewSet
    2 class ZhongJiBanView(ModelViewSet):
    3     queryset = UserInfo.objects.all()
    4     serializer_class = UserModelSerializer

    直接继承了一个巨无霸(ModelViewSet),这个巨无霸将所有的功能都封装到一块。相当于把我们从第一版到第三版写的所有事情都干了,

    按照老规矩,我们来看看它的源码:

    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericViewSet):
        """
        A viewset that provides default `create()`, `retrieve()`, `update()`,
        `partial_update()`, `destroy()` and `list()` actions.
        """
        pass

    从源码中能看出,ModelViewSet所继承的视图类

    urls.py

    1 from . import views
    2 from rest_framework.routers import DefaultRouter
    3 rount = DefaultRouter()
    4 rount.register('user',views.ZhongjiBanView)
    5 urlpatterns = []
    6 urlpatterns += rount.urls

    最终版的规则使用了drf的DefaultRouter函数,通过实例化DefaultRouter得到route对象,使用route.register()你的app路由,有多个注册多个即可

  • 相关阅读:
    python微信机器人
    爬取糗事百科,微信自动发送
    验证码破解
    [Python]机器学习【推荐】
    [Python]利用jieba.analyse进行 关键词 提取
    《将博客搬至CSDN》
    [极限测试]第一日进度
    [Python]调用百度API进行自然语言处理 标签、关键字 以及 词法分析
    学习进度报告【第三周】
    [Python]调用百度地图API对地点进行搜索,利用 JSON 返回纬度/行政区域编号
  • 原文地址:https://www.cnblogs.com/lvye001/p/9885252.html
Copyright © 2020-2023  润新知