zoukankan      html  css  js  c++  java
  • Python 视图类传递参数给序列化类 视图家族:GenericAPIView基类

    context:视图类传递参数给序列化或反序化类

    # 1)在视图类中实例化序列化或反序列化对象时,可以设置context内容
    # 2)在序列化类中的局部钩子、全局钩子、create、update方法中,都可以用self.context访问视图类传递过来的内容
    
    
    # 需求:
    # 1) 在视图类中,可以通过request得到登陆用户request.user
    # 2) 在序列化类中,要完成数据库数据的校验与入库操作,可能会需要知道当前的登陆用户,但序列化类无法访问request
    # 3) 在视图类中实例化序列化对象时,将request对象传递进去

     视图层:views.py

    class Book(APIView):
        def post(self, request, *args, **kwargs):
            book_ser = serializers.BookModelSerializer(data=request_data,context={'request':request})
            book_ser.is_valid(raise_exception=True)
            book_result = book_ser.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': serializers.BookModelSerializer(book_result).data
            })

     序列化层:serializers.py

    class BookModelSerializer(ModelSerializer):
        class Meta:
            model = models.Book
            fields = ('name', 'price')
        def validate_name(self, value):
            print(self.context.get('request').method)
            return value

     二次封装response类

    (总体思路:将要展示给前端的数据,以字典的形式赋值给父类(Response的data,让父类完成初始化即可

    原生的Response使用

    """
    return Response({
          'status': 0,
          'msg': 'ok',
          'results': [],
          'token': ''  # 有这样的额外的key-value数据结果
        },status=http_status,headers=headers,exception=True|False)
    
    APIResponse() => Response({'status': 0,'msg': 'ok'})
    """

    1.二次封装response类,就可以使用自己二次封装的类来定义响应数据的格式拓展性较高。

    2.定义使用

    #1.创建文件夹:utils(与app应用文件夹 ,同级目录)

    #2.创建文件:response.py(utils文件夹中创建); 并在response.py文件中编写代码

    (总体思路:将要展示给前端的数据,以字典的形式赋值给父类(Response的data,让父类完成初始化即可


    from
    rest_framework.response import Response class APIResponse(Response): def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=False, **kwargs): # data的初始状态:状态码与状态信息 data = { 'status': data_status, 'msg': data_msg, } # data的响应数据体 # results可能是False、0等数据,这些数据某些情况下也会作为合法数据返回 if results is not None: data['results'] = results # data响应的其他内容 # if kwargs is not None: # for k, v in kwargs.items(): # setattr(data, k, v) data.update(kwargs) super().__init__(data=data, status=http_status, headers=headers, exception=exception)

    #3.cbv中的类使用

    # 1.将自定义响应类导入
    from rest_framework.views import APIView
    
    # 2.cbv中使用
     return APIResponse(0, '删除成功')

    视图家族

    """
    1.views:视图
    2.generics:工具视图:#1.GenericAPIView基类(2属性3方法);#2.(只需要提供2属性即可)  群查单增:ListCreateAPIView 单整改和单局改UpdateAPIView等等,一般用的就是这2个类,
          如果cbv全部继承的话可能会报错。 3.mixins:视图工具集:5类6个方法 4.viewsets:视图集:#1.
    GenericViewSet、ViewSet:路由(请求方式对应自定义函数),使用方法结合mixins视图工具集;#2.
    """
    """
    学习曲线
    APIView => GenericAPIView => mixins的五大工具类 => generics中的工具视图 => viewsets中的视图集
    总结:2,3,4全部都要提供2属性
    """

    工具视图:#1.GenericAPIView基类(generics.GenericAPIView:2属性3方法)

    # GenericAPIView是继承APIView的,使用完全兼容APIView
    # 重点:GenericAPIView在APIView基础上完成了哪些事

    获取多个对象 #
    1)get_queryset():从类属性queryset中获得model的queryset数据
    获取单个对象 # 2)get_object():从类属性queryset中获得model的queryset数据,再通过有名分组pk确定唯一操作对象
    序列化和反序列化 # 3)get_serializer():从类属性serializer_class中获得serializer的序列化类

      # 自定义主键的 有名分组 名
      lookup_field = 'pk'

    路由:

    urlpatterns = [
        url(r'^v2/books/$', views.BookGenericAPIView.as_view()),
        url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
    ]

    视图:

    class BookGenericAPIView(generics.GenericAPIView):
        queryset = models.Book.objects.filter(is_delete=False).order_by('-id')
        serializer_class = serializers.BookModelSerializer
        # 自定义主键的 有名分组 名
        lookup_field = 'pk'
    
        def get(self, request, *args, **kwargs):
            if 'pk' in kwargs:
                book_obj = self.get_object()
                book_ser = self.get_serializer(book_obj)
                return APIResponse(0, 'ok', results=book_ser.data)
            book_query = self.get_queryset()
            book_ser = self.get_serializer(book_query, many=True)
            return APIResponse(0, 'ok', results=book_ser.data)
    
        def post(self, request, *args, **kwargs):
            book_ser = self.get_serializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_obj = book_ser.save()
            return APIResponse(0, 'ok', results=self.get_serializer(book_obj).data)

    mixins视图工具集 - 辅助GenericAPIView

    # 1)继承5类,使用6方法:mixins有五个工具类文件,一共提供了五个工具类,六个工具方法:单查、群查、单增、单删、单整体改、单局部改
    # 2)必须继承GenericAPIView和提供2属性:继承工具类可以简化请求函数的实现体,但是必须继承GenericAPIView,需要GenericAPIView类提供的几个类属性和方法(见上方GenericAPIView基类知识点)
    # 3)工具类的工具方法返回值都是Response类型对象,如果要格式化数据格式再返回给前台,可以通过 response.data 拿到工具方法返回的Response类型对象的响应数据

    # 路由

    urlpatterns = [
           url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
        url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
    ]

    # 视图

    from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
    class BookMixinGenericAPIView(ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericAPIView):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
        # 单查 群查
        def get(self, request, *args, **kwargs):
            if 'pk' in kwargs:
                response = self.retrieve(request, *args, **kwargs)
            else:
                # mixins提供的list方法的响应对象是Response,想将该对象格式化为APIResponse
                response = self.list(request, *args, **kwargs)
            # response的数据都存放在response.data中
            return APIResponse(results=response.data)
        # 单增
        def post(self, request, *args, **kwargs):
            response = self.create(request, *args, **kwargs)
            return APIResponse(results=response.data)
        # 单整改
        def put(self, request, *args, **kwargs):
            response = self.update(request, *args, **kwargs)
            return APIResponse(results=response.data)
        # 单局改
        def patch(self, request, *args, **kwargs):
            response = self.partial_update(request, *args, **kwargs)
            return APIResponse(results=response.data)

    工具视图:#2.

    # 1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
    # 2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
    
    #3)ListCreateAPIView:群查单增, UpdateAPIView:单整改,单局改;一般用的就是这2个类,如果cbv全部继承的话可能会报错。
    
    

    路由

    urlpatterns = [
           url(r'^v4/books/$', views.BookListCreatePIView.as_view()),
        url(r'^v4/books/(?P<pk>.*)/$', views.BookListCreatePIView.as_view()),
    ]

    视图

    from rest_framework.generics import ListCreateAPIView, UpdateAPIView
    class BookListCreatePIView(ListCreateAPIView, UpdateAPIView):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer

    视图集

    # 1)视图集都是优先继承ViewSetMixin类,再继承一个视图类(GenericAPIView或APIView)
    #       GenericViewSet、ViewSet
    # 2)ViewSetMixin提供了重写的as_view()方法,继承视图集的视图类,配置路由时调用as_view()必须传入 请求名-函数名 映射关系字典
    #       eg: url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
    #       表示get请求会交给my_get_list视图函数处理
    # 3)s总结:结合mixins视图工具集使用,和mixins使用没什么区别,只是路由指定了请求和cbv的方法的对应在多继承一个类

    视图集:#1.GenericViewSet、ViewSet

    路由:

    urlpatterns = [
           # View的as_view():将get请求映射到视图类的get方法
        # ViewSet的as_view({'get': 'my_get_list'}):将get请求映射到视图类的my_get_list方法
        url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
        url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({'get': 'my_get_obj'})),
    ]

    视图

    from rest_framework.viewsets import GenericViewSet
    from rest_framework import mixins
    class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    
        def my_get_list(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def my_get_obj(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)

    GenericAPIView 与 APIView 最为两大继承视图的区别

    # 1)GenericViewSet和ViewSet都继承了ViewSetMixin,as_view都可以配置 请求-函数 映射
    # 2)GenericViewSet继承的是GenericAPIView视图类,用来完成标准的 model 类操作接口
    # 3)ViewSet继承的是APIView视图类,用来完成不需要 model 类参与,或是非标准的 model 类操作接口
    #       post请求在标准的 model 类操作下就是新增接口,登陆的post不满足
    #       post请求验证码的接口,不需要 model 类的参与
    # 案例:登陆的post请求,并不是完成数据的新增,只是用post提交数据,得到的结果也不是登陆的用户信息,而是登陆的认证信息

    视图集:#2.工具视图集

    源码:

    # 1.使用方式和工具视图一样提供2属性,拥有六大接口:单查、群查、单增、单删、单整体改、单局部改
    # 2.路由和视图集一样 as_view({'请求方式':'6个方法'}),方法是mixins中的6个不再是自定义的
    # 3.注:一般肯定会重写destroy

    路由:

    urlpatterns = [
           url(r'^v6/books/$', views.BookModelViewSet.as_view({'get': 'list', 'post': 'create'})),
        url(r'^v6/books/(?P<pk>.*)/$', views.BookModelViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
    ]

    视图:

    from rest_framework.viewsets import ModelViewSet
    class BookModelViewSet(ModelViewSet):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    
        # 删不是数据库,而是该记录中的删除字段
        def destroy(self, request, *args, **kwargs):
            instance = self.get_object()  # type: models.Book
            if not instance:
                return APIResponse(1, '删除失败')  # 实际操作,在此之前就做了判断
            instance.is_delete = True
            instance.save()
            return APIResponse(0, '删除成功')

    路由组件(了解)

    from django.conf.urls import include
    from rest_framework.routers import SimpleRouter
    router = SimpleRouter()
    # 所有路由与ViewSet视图类的都可以注册,会产生 '^v6/books/$' 和 '^v6/books/(?P<pk>[^/.]+)/$'
    router.register('v6/books', views.BookModelViewSet)
    
    urlpatterns = [
        # 第一种添加子列表方式
        url(r'^', include(router.urls)),
    ]
    # 第二种添加子列表方式
    # urlpatterns.extend(router.urls)
  • 相关阅读:
    7.21 高博教育 数组 内存
    【基础扎实】Python操作Excel三模块
    PAT 甲级 1012 The Best Rank
    PAT 甲级 1011  World Cup Betting
    PAT 甲级 1010 Radix
    链式线性表——实验及提升训练
    循环程序设计能力自测
    链表应用能力自测
    PAT 甲级 1009 Product of Polynomials
    1008 Elevator (20分)
  • 原文地址:https://www.cnblogs.com/tfzz/p/11699491.html
Copyright © 2011-2022 走看看