• vue day(71)


    rest_framework

    它是基于Django的一种服务框架,可以帮助我们快速开发符合RESTful规范的接口框架。

    功能:
    
    1.路由
    
    2.视图
    
    3.版本
    
    4.认证
    
    5.权限
    
    6.频率
    
    7.解析器
    
    8.序列化
    
    9.分页
    
    10.渲染器
    

    在setting中配置,rest_framework实质上是一个app,需要注册才可以使用

    1. rest_framework框架的封装规范

    from rest_framework.views import APIView    //视图
    from rest_framework.request import Request  //请求
    from rest_framework.response import Response    //响应
    from rest_framework.exceptions import APIException  //异常
    from rest_framework.pagination import PageNumberPagination  //分页
    from rest_framework.settings import APISettings //设置settings
    from rest_framework.parsers import JSONParser   //解析
    from rest_framework.filters import OrderingFilter   //筛选
    

    drf框架自定义配置

    cbv中的类直接继承APIView

    class BookAPIView(APIView):
        pass
    

    在settings中自定义,里面可以设置相应的

    REST_FRAMEWORK = {
        
    }
    

    2. APIView

    csrf验证不限制

    原生django受csrf限制,而drf不受csrf认证限制

    # django 的视图类
    from django.views import View
    from django.http import JsonResponse
    class BookView(View):
        def get(self,request,*args,**kwargs):
            return JsonResponse({
                'msg':'view get ok'
            })
        def post(self,request,*args,**kwargs):
            return JsonResponse({
                'msg':'view post ok'
            })
    
    # 使用APIView
    from rest_framework.views import APIView
    from rest_framework.response import Response
    class BookAPIView(APIView):
        def get(self,request,*args,**kwargs):
            return Response({
                'msg':'view get ok'
            })
        # post方法不需要注释csrf照样可以传递
        def post(self,request,*args,**kwargs):
            return Response({
                'msg':'view post ok'
            })
    

    3. APIView生命周期

    1.APIView类继承了View类,重写了as_view方法和dispatch方法

    2.重写的as_view方法,主体还是View的as_view,只是在返回视图view函数地址时,局部禁用csrf认证

    3.重写了dispatch方法

    • 在执行请求逻辑前:请求模块(二次封装request),解析模块(三种数据包格式的数据解析)
    • 在执行请求逻辑中:异常模块(执行出现任何异常交给异常处理模块处理)
    • 在执行请求逻辑后:响应模块(二次封装response),渲染模块(响应的数据能被JSON和页面两种渲染)
    dispatch方法:
            二次封装request对象()
                包含解析模块
            三大认证:
                (认证.权限.频率),用来替换csrf安全认证,要比csrf认证强大的多
            异常模块:
                处理请求异常通知,所有的API类异常都交由它处理self.handle_exception(exc)
            二次封装response
                处理了结果渲染,包含许多渲染模块
    

    技术图片

    1. 启动django项目

    2. 加载settings.py文件

    3. 读取models.py文件

    4. 加载views.py文件

    5. 加载urls.py文件

    6. 执行urls.py文件

      url(r'^book/(?P<pk>d+)/$',views.BookAPIView.as_view())
      执行views.BookAPIView.as_view()函数方法
      

      技术图片

    3.1 请求模块

    • 将wsgi的request对象转化成drf的Request类的对象
    • 封装后的request对象完全兼容wsgi的request对象,并且将原request保存在新request._request中
    • 重新格式化请求数据存放位置
    拼接参数:
        request.query_params
    数据包参数:
        request.data
    print(request._request.method)  # 在内部将wsgi的request赋值给了request._request
    print(request.method)   # 就是通过__getattr__走的是request._request.method
    print(request.query_params) # 走的是方法属性,就是给request._request.GET重新命名
    print(request.data) #走的是方法属性,依赖于request._full_data
    

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    img

    3.2 解析模块

    img

    只处理数据包参数

    json                // 'rest_framework.parsers.JSONParser',
    urlencoded          // 'rest_framework.parsers.FormParser',
    form-data           // 'rest_framework.parsers.MultiPartParser',
    
    • 全局配置所有视图类的解析方式,解析配置可以配置三种
    • 局部配置当前视图类的解析方式,解析配置可以配置三种
    • 配置的查找顺序: 局部(视图类的类属性) => 全局(settings文件的drf配置) => 默认(drf的默配置)

    注: 该模块了解,但是全局局部配置是重点

    局部配置

    在views中设置
    from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
    class BookAPIView(APIView):
        parser_classes = [JSONParser,FormParser,MultiPartParser]
        def get(self,request,*args,**kwargs):
            pass
        def post(self,request,*args,**kwargs):
            pass
    

    全局配置

        在settings中配置
            REST_FRAMEWORK = {
                'DEFAULT_PARSER_CLASSES': [
                    'rest_framework.parsers.JSONParser',
                    'rest_framework.parsers.FormParser',
                    'rest_framework.parsers.MultiPartParser',
                ],
            }
    

    默认配置

    drf自身的设置
    在APIView类中的rest_framework.settings.APISettings
    

    3.3 响应模块

    img

    data: 响应数据
    
    status: 响应的网络状态码
    
    ---------------------------------------------------------
    
    template_name: drf完成前后台不分离返回页面,但是就不可以返回data(不需要了解)
    
    headers: 响应头,一般不规定,走默认
    
    exception: 一般异常响应,会将其设置成true,默认为False(不设置也没事)
    
    content_type: 默认就是application/json,不需要处理
    

    代码

    # 响应模块状态码
    from rest_framework import status
    class BookAPIView(APIView):
        # 响应模块可以自定义返回的数据
        def get(self,request,*args,**kwargs):
            response = Response(
                data={
                    'msg':'apiview get ok'
                },
                status=status.HTTP_404_NOT_FOUND
            )
    

    3.4 渲染模块(了解)

    Postman请求结果是json,浏览器请求结果是页面

    可以全局与局部配置
    'rest_framework.renderers.JSONRenderer',    // 渲染json
    'rest_framework.renderers.BrowsableAPIRenderer',    // 渲染浏览器界面,项目上线尽量关闭
    

    全局配置

    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',
        ],
    }
    

    局部配置

    # 渲染模块
    from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
    class BookAPIView(APIView):
        # 局部配置渲染类,只适用当前视图类
        renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
    

    3.5 异常模块

    源码分析

    # 异常模块:APIView类的dispatch方法中
    response = self.handle_exception(exc)  # 点进去
    
    # 获取处理异常的句柄(方法)
    # 一层层看源码,走的是配置文件,拿到的是rest_framework.views的exception_handler
    # 自定义:直接写exception_handler函数,在自己的配置文件配置EXCEPTION_HANDLER指向自己的
    exception_handler = self.get_exception_handler()
    
    # 异常处理的结果
    # 自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response一定有值
    response = exception_handler(exc, context)
    

    img

    img

    img

    img

    img

    img

    img

    img

    自定义异常处理

    首先在settings文件中设置
    
    REST_FRAMEWORK = {
        # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
        # 配置自定义的报错函数路径
        'EXCEPTION_HANDLER': 'api.exception.exception_handler',
    }
    

    需要重写exception_handle方法,并使用系统默认的处理函数

    # 自定义报错的界面
    # 一定要在settings文件中将异常模块配置自己的异常处理函数
    
    from rest_framework.response import Response
    # 导入异常模块处理的函数,并起了个别名
    from rest_framework.views import exception_handler as drf_exception_handler
    def exception_handler(exc,content):
        # 获取异常模块处理过的异常信息
        response = drf_exception_handler(exc,content)
        # 拼接报错信息
        detail = '%s - %s - %s' % (content.get('view'),content.get('request').menthod,exc)
        # 如果没有信息,就是服务端错误
        if not response:
            response = Response({'detail':detail})
        else:
            response.data = {'detail':detail}
        # 核心: 要将response.data.get('detail') 信息记录到日志文件
        print( response.data.get('detail'))
        return response
    

    代码

    from rest_framework.views import exception_handler as drf_exception_handler
    from rest_framework.response import Response
    from rest_framework import status
    
    def exception_handler(exc, context):
        # 1.先让drf的exception_handler做基础处理,拿到返回值
        # 2.若有返回值则drf处理了,若返回值为空说明drf没处理,需要我们手动处理
        response = drf_exception_handler(exc, context)
        print(exc)   # 错误内容 'NoneType' object has no attribute 'title'
        print(context)
        # {'view': <api.views.Book object at 0x000001BBBCE05B00>, 'args': (), 'kwargs': {'pk': '3'}, 'request': <rest_framework.request.Request object at 0x000001BBBCF33978>}
        print(response)
        # 返回值为空,做二次处理
        if response is None:
            print('%s - %s - %s' % (context['view'], context['request'].method, exc))
            # <api.views.Book object at 0x00000242DC316940> - GET - 'NoneType' object has no attribute 'title'
            return Response({
                'detail': '服务器错误'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
        return response
    
  • 相关阅读:
    EXCEL中用VLOOKUP功能,根据A列的值,把B列也填充上对应的值
    ReNamer批量重命名文件,如何给杂乱无章的文件名重新命名
    小米手机亲情守护(风筝守护)怎么解绑?
    PHP正则表达式遇到的一个utf8乱码坑
    筹米网你用过没?是套路还是真能帮你提前抢购域名?
    CSS选取第一个、最后一个、偶数、奇数、第n个标签元素
    winscp会话超时及尝试关闭优化连接缓冲大小
    Linux下压缩和解压
    一步一步学Linux下vi/vim的使用(案例比纯理论好学)
    Linux使用find命令,搜索文件名中带有通配符*,报错: paths must precede expression
  • 原文地址:https://www.cnblogs.com/LZF-190903/p/12116056.html
Copyright © 2020-2023  润新知