zoukankan      html  css  js  c++  java
  • 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路由,有多个注册多个即可

  • 相关阅读:
    基于Metaweblog API 接口一键发布到国内外主流博客平台
    uva144 Student Grants
    Uva 10452
    Uva 439 Knight Moves
    Uva 352 The Seasonal War
    switch语句
    java——基础知识
    我的lua学习2
    codeforces 431 D. Random Task 组合数学
    codeforces 285 D. Permutation Sum 状压 dfs打表
  • 原文地址:https://www.cnblogs.com/lvye001/p/9885252.html
Copyright © 2011-2022 走看看