• 六、python Django REST framework增删改查[视图、扩展类、扩展类的子类、视图集]


    一、视图

    重点:请先认真读完下面的内容再进行深入学习,或者先跳过当有不懂的时候,回头再看看下面的话


    视图包括下面一会介绍的视图集知识点,都是由繁琐简单,最后只需几行就可实现复杂功能(此类功能大多为死板的增删改查,不够灵活),重点就在互相之间的继承,通过前面学习繁琐的代码就能逐步知其然知其所以然,并且利于自己实现特别的需求

    RESTful接口规范:为什么要先说这个呢?因为Django REST基于RESTful接口规范来实现的功能。RESTful接口规范指出,要根据不同的需求对应不同的请求方式,比如查询使用GET删除使用DELETE增加使用POST
    固定模式(Django rest也会用到):
    GET 127.0.0.1/products :将返回所有产品清单
    GET 127.0.0.1/products/4 :将获取产品 pk值=4
    POST 127.0.0.1/products :将产品新建到集合
    PUT 127.0.0.1/products/4 :将更新产品 pk值=4
    DELETE 127.0.0.1/products/4 :将删除 pk值=4的产品
    特别的需求
    PUT 127.0.0.1/products/4/news :这个与上面不同就是4后面加了个news,这个news就属于自己定义的,其意思可以为将 pk值为4的商品的某项功能更新(与上面不同就是这里"更新"属于自己特殊需求写的代码

    pycharm debug:为了方便了解继承关系
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    1.APIView

    Request与HttpRequeset区别:Request的request.data属性即可获取表单类型数据或者JSON数据,无需HttpRequeset这么麻烦;Request的request.query_params等同于HttpRequeset里面的request.GET

    导入:from rest_framework.views import APIView

    介绍:APIViewREST framework提供的所有视图的基类,继承自Django的View父类,其大体与View用法一样,但有些不同下面马上会介绍。

    不同

    1. 传入到视图方法中的是REST framework封装好的Request对象,而不是Django的HttpRequeset对象(前言里面介绍了他们的区别)

    2. 视图方法可以返回REST framework的Response对象,不使用之前文章的类似HttpResponse等,直接光一个Response对象就能适合的返回前端需要的数据

    3. 在进行dispatch()分发前,会对请求进行身份认证权限检查流量控制

    关系图谱:
    在这里插入图片描述
    urls.py

    urlpatterns = [
            path("teacher", views.TestAPIView.as_view())
    ]
    
    • 1
    • 2
    • 3

    views.py

    from rest_framework.views import APIView
    from .models import Student, Teacher
    from .serializers import StudentSerializer
    from rest_framework.response import Response
    class TestAPIView(APIView):
        def get(self, request):
            data = Student.objects.all()
            serializer = StudentSerializer(instance=data, many=True)
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.GenericAPIView

    导入:from rest_framework.generics import GenericAPIView

    介绍:继承自APIVIew,增加了对于列表视图(就是获取表单全部数据)和详情视图(表单具体数据)可能用到的通用支持方法。通常使用时,可搭配一个或多个Mixin扩展

    关系图谱:
    在这里插入图片描述

    代码分析:

    1. 获取全部
      path("teachers", views.TestGenericAPIView.as_view())
    class TestGenericAPIView(GenericAPIView):
        queryset = Student.objects.all() 
        ''' 
        GenericAPIView里面设置了queryset ,
        其会在GenericAPIView的get_queryset()函数里面调用
        '''
        serializer_class = StudentSerializer
        ''' 
        GenericAPIView里面设置了serializer_class ,
        其会在GenericAPIView的get_queryset()函数里面调用
        '''
        def get(self, request):
            book = self.get_queryset()
        ''' 
        get_queryset属于父类GenericAPIView里面的函数
        其用法比较简单,含义≈data = Student.objects.all()
        注意重点起到校验检查的作用
        '''
            serializer = self.get_serializer(book, many=True)
        ''' 
        get_serializer属于父类GenericAPIView里面的函数
        其主要是为serializer添加了一个context属性request、format、view
        这三个数据对象可以在定义序列化器时使用
        效果≈serializer = StudentSerializer(instance=data, many=True,context=)
        
        '''
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. 获取单个
      path("teachers/", views.TestGenericAPIView.as_view())
    class TestGenericAPIView(GenericAPIView):
        queryset = Student.objects.all()
    
        serializer_class = StudentSerializer
    
        def get(self, request, pk):
            book = self.get_object()
       ''' 
       注意:get(self, request, pk)中参数pk是必填的必须这样写的,其在GenericAPIView被写死
       get_object()起初通过源码"queryset = self.filter_queryset(self.get_queryset())",
       获取验证并获取A=Student.objects.all()对象,但不要以为它向服务器发送获取全部数据的请求,
       因为下面"obj = get_object_or_404(queryset, **filter_kwargs)"会发送类似A.get(id=pk)
       的请求(A是Student.objects.all()),django会发送最终的请求(即不用不发)
       '''
            serializer = self.get_serializer(book)
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二、扩展类

    这几个扩展类都大同小异,只详细介绍一个

    关系图谱:
    在这里插入图片描述

    1. ListModelMixin

    导入:from rest_framework.mixins import ListModelMixin

    介绍:属于获取全部的简写,其依赖于继承GenericAPIView(必须与其一起被其它程序继承),其属于是一个整合,没有实际的基础代码

    代码分析:

    path("teachers", views.TestGenericAPIView.as_view())

    class TestGenericAPIView(ListModelMixin,GenericAPIView):
        queryset = Teacher.objects.all()
    
        serializer_class = TeacherSerializer
    
        def get(self, request):
            return self.list(request)
       # ListModelMixin里面的一个函数叫做list(),其实现功能与我刚刚上面才单继承GenericAPIView写的大同小异
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. RetrieveModelMixin

    导入:from rest_framework.mixins import RetrieveModelMixin

    介绍:属于获取单个的简写,其属于是一个整合

    代码:

    path("teachers/", views.TestGenericAPIView.as_view())

    class TestGenericAPIView(RetrieveModelMixin, GenericAPIView):
        queryset = Teacher.objects.all()
    
        serializer_class = TeacherSerializer
    
        def get(self, request, pk):
            return self.retrieve(request)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. CreateModelMixin

    导入:from rest_framework.mixins import CreateModelMixin

    介绍:属于创建的简写,其属于是一个整合

    代码分析:

    path("teachers/", views.TestGenericAPIView.as_view())

    class TestGenericAPIView(CreateModelMixin, GenericAPIView):
        queryset = Teacher.objects.all()
    
        serializer_class = TeacherSerializer
        
        def post(self, request, pk):
            return self.create(request)
       # 来自CreateModelMixin的create(),里面使用上一篇文章序列化里面新增的知识
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. UpdateModelMixin

    导入:from rest_framework.mixins import UpdateModelMixin

    介绍:属于创建的简写,其属于是一个整合

    代码分析:

    path("teachers", views.TestGenericAPIView.as_view())
    path("teachers/", views.TestGenericAPIView.as_view())

    class TestGenericAPIView(RetrieveModelMixin, UpdateModelMixin, GenericAPIView):
        queryset = Student.objects.all()
    
        serializer_class = StudentSerializer
    
        def get(self, request, pk):
            return self.retrieve(request)
    
        # def put(self, request, pk):
        #     return self.update(request) # 全部更新
        
    	# 使用update时,如果在序列化时没有专门设置,名称属性required=False,默认就需要提供全部数据才能进行更新
        def put(self, request, pk):
            return self.partial_update(request) # 局部更新
       # 使用partial_update时,如果在序列化时没有专门设置,名称属性required=False,也可以提供部分值就能成功更新数据,原理是:使用partial_update在UpdateModelMixin里面partial的参数为true;而update是false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5. DestroyModelMixin

    导入:from rest_framework.mixins import DestroyModelMixin

    介绍:属于删除的简写,其属于是一个整合

    代码:

    path("teachers", views.TestGenericAPIView.as_view())
    path("teachers/", views.TestGenericAPIView.as_view())

    class TestGenericAPIView(RetrieveModelMixin, DestroyModelMixin, GenericAPIView):
        queryset = Student.objects.all()
    
        serializer_class = StudentSerializer
    
        def get(self, request, pk):
            return self.retrieve(request)
    
        def delete(self, request, pk):
            return self.destroy(request)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、扩展类的子类

    1.CreateAPIView

    导入:from rest_framework.generics import CreateAPIView

    解释:用来创建,继承+post,其继承GenericAPIView, CreateModelMixin

    class TestGenericAPIView(CreateAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    # 这样就实现了上面介绍CreateModelMixind的功能
    
    • 1
    • 2
    • 3
    • 4

    2.ListAPIView

    导入:from rest_framework.generics import ListAPIView

    解释:用来查全部,继承+get,其继承GenericAPIView、ListModelMixin

    class TestGenericAPIView(ListAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    # 这样就实现了上面介绍ListModelMixin的功能
    
    • 1
    • 2
    • 3
    • 4

    3.RetrieveAPIView

    导入:from rest_framework.generics import RetrieveAPIView

    解释:用来查单个,继承+get,其继承GenericAPIView、RetrieveModelMixin

    class TestGenericAPIView(RetrieveAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    # 这样就实现了上面介绍RetrieveModelMixin的功能
    
    • 1
    • 2
    • 3
    • 4

    4.DestroyAPIView

    导入:from rest_framework.generics import DestroyAPIView

    解释:用来删除单个,继承+delete ,其继承GenericAPIView、DestroyModelMixin

    class TestGenericAPIView(DestroyAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    # 这样就实现了上面介绍DestoryModelMixin的功能
    
    • 1
    • 2
    • 3
    • 4

    5.UpdateAPIView

    导入:from rest_framework.generics import UpdateAPIView

    解释:用来修改,继承+put(改全部)+patch(改单个) ,其继承GenericAPIView、UpdateModelMixin

    class TestGenericAPIView(UpdateAPIView):
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    # 这样就实现了上面介绍UpdateModelMixin的功能
    
    • 1
    • 2
    • 3
    • 4

    6. RetrieveUpdateAPIView

    解释:提供 get、put、patch方法

    7. RetrieveUpdateDestroyAPIView

    解释:提供 get、put、patch、delete方法

    四、视图集

    解释:视图集提供下面五种方式,具体能用什么,看你继承什么,与需要,配合url填入

    1. list() 提供一组数据
    2. retrieve() 提供单个数据
    3. create() 创建数据
    4. update() 保存数据
    5. destroy() 删除数据

    1. ViewSet

    导入:from rest_framework.viewsets import ViewSet

    说明:其先继承了ViewSetMixin再继承APIView,所以其为基础类

            path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
            path("teachers/", views.TestGenericAPIView.as_view({'get':'retrieve'}))
    
    • 1
    • 2
    class TestGenericAPIView(ViewSet):
    	
    	'''
    	其不使用get(),post()方法
    	但是它通过ViewSetMixin的as_view()提供的参数(在ViewSetMixin为actions),根据对应关系创建了get,put,delete等请求
    	然后其发送给APIView的dispatch去类似于扩展类一样去分发给get、post、delete等等
    	'''
        def list(self, request):
            data = Student.objects.all()
            serializer = StudentSerializer(instance=data,many=True)
            return Response(serializer.data)
    
        def retrieve(self, request, pk):
            data = Student.objects.all().get(id=pk)
            serializer = StudentSerializer(instance=data)
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2. GenericViewSet

    导入:from rest_framework.viewsets import GenericViewSet

    说明:其先继承了ViewSetMixin再继承GenericAPIView,重点提供get_objectget_queryset等属性与方法,所以较为基础类

            path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
            path("teachers/", views.TestGenericAPIView.as_view({'get':'retrieve'}))
    
    • 1
    • 2
    class TestGenericAPIView(GenericViewSet):
    
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    
        def list(self, request):
            data = self.get_queryset()
            serializer = self.get_serializer(data,many=True)
            return Response(serializer.data)
    
        def retrieve(self, request, pk):
            data = self.get_object()
            serializer = self.get_serializer(data)
            return Response(serializer.data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.ModelViewSet

    导入:from rest_framework.viewsets import ModelViewSet

    说明:继承自GenericAPIVIew,同时包括了ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestoryModelMixin

            path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
            path("teachers/", views.TestGenericAPIView.as_view({'get':'retrieve', 'delete':'destroy'}))
    
    • 1
    • 2
    class TestGenericAPIView(ModelViewSet):
    
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    
    • 1
    • 2
    • 3
    • 4

    4.ReadOnlyModelViewSet

    导入:from rest_framework.viewsets import ReadOnlyModelViewSet
    说明:继承自GenericAPIVIew,同时包括了ListModelMixinRetrieveModelMixin,用来获取数据

            path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
            path("teachers/", views.TestGenericAPIView.as_view({'get':'retrieve'}))
    
    • 1
    • 2
    class TestGenericAPIView(ReadOnlyModelViewSet):
    
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    	# 只读只剩下list()和retrieve()方法了
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5. 自定义

    path("teachers/lastsome", views.TestGenericAPIView.as_view({'get':'lastsome'})),
    
    • 1
    class TestGenericAPIView(ReadOnlyModelViewSet):
    
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
    
        def lastsome(self, request):
    
            data = Student.objects.get(id=7)
            serializer = StudentSerializer(instance=data)
            a = serializer.data
            a.pop('time')
            return Response(a)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    关于第一方数据,你必须要知道的三件事
    计算机网络:运输层 - TCP 流量控制 & 拥塞控制
    【每日一题】二叉树中和为某一值的路径
    EasyX库的下载及基本作图函数的使用【VS编译器】
    Windows风格的个人网盘,支持文档在线编辑
    TResNet: ResNet改进,实现高精度的同时保持高 GPU 利用率
    Java返回日期格式问题
    7(第六章,数据存储和操作)
    Spring-MVC
    zynq平台蓝牙协议栈移植
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/126184373