zoukankan      html  css  js  c++  java
  • 1224 rest_framework框架的封装特点

    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
    
  • 相关阅读:
    STL标准库algorithm中remove()函数的一个小注意事项
    关于 mem_fun_ref 和 bind2nd的疑问
    记录昨日程序调不通的解释
    复习几个C++概念:声明与定义、传值与拷贝构造、初始化和赋值
    对stl map 赋值添加元素的疑惑 求解(管理员让这个帖子多见会人吧~~谢谢啦!)
    摘抄书上一个逆序字符串的例子(可根据不同的符号,比如*&,.;来拆分单词)
    “指向指针的引用”小例子:忽然豁然开朗~
    论文 “tracking evolving communities in large linked networks” 中不懂的问题和知识总结
    [wp7软件]wp7~~时间日程 软件大全! 集合贴~~~
    [wp7游戏]wp7~~超级血腥类游戏~~集合贴~~
  • 原文地址:https://www.cnblogs.com/fwzzz/p/12094171.html
Copyright © 2011-2022 走看看