DRF-APIView

一、APIView请求生命周期

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

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

3、重写的dispatch方法:

​ 在执行请求逻辑前:请求模块(二次封装request)、解析模块(三种数据包格式的数据解析);

​ 在执行请求逻辑中:异常模块(执行出现任何异常交个异常模块处理)

​ 在执行请求逻辑后:响应模块(二次封装response)、渲染模块(响应的数据能JSON和页面两种渲染);

二、请求模块

1、将wsgi的request对象转化成drf的Request类对象;

2、封装后的request对象完全兼容wsgi的request对象,并且将原request保存在新的request._request;

3、重写格式化请求数据存放位置:

​ 拼接参数:request.query_params

​ 数据包参数:request.data

#源码解析:
#入口:APIview的dispatch方法的request=self.initialize_request(request,*args,**kwargs)

#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

三、解析模块

1、全局配置所有视图类的解析方式,解析配置可以配置三种;

2、局部配置当前视图类的解析方式,解析配置可以配置三种;

3、配置低的查找顺序:局部(视图类的类属性)=>全局(setting文件的drf配置)=>默认(drf的默认配置);

注:全局局部配置是重点。
局部:

全局:

#源码解析:
#入口:APIView的dispatch方法的request=self.instialize_request(request,*args,**kwargs)
#获取解析类:parsers = self.get_parsers(),
#进行局部-全局-默认配置查找顺序进行查找:
return [parser() for parser in self.parser_classes]
#局部配置(在视图类中配置):
parser_classes = [JSONParser, FormParser, MultiPartParser]
#全局配置(在setting中配置):
'DEFAULT_PARSER_CLASSES': [
     'rest_framework.parsers.JSONParser',
     'rest_framework.parsers.FormParser',
     'rest_framework.parsers.MultiPartParser'
   ],

四、响应模块

'data':响应数据(熟悉)
'status':响应的网络状态码(熟悉)


template_name:drf完成前后台不分离返回页面,但是就不可以返回data(不需要掌握)

headers:响应头,一般不规定,走默认

exception:一般异常响应,会将其设置成True,默认False(不设置也没事)

content_type:默认就是application/json不需要处理

五、渲染模块(了解)

Postman软件测试请求结果是json,浏览器请求结果是页面
局部:

全局:

#局部配置渲染类(在视图类中配置):只适用当前视图类
    renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
#全局配置渲染类:适用于所有视图类
'DEFAULT_RENDERER_CLASSES': [
    'rest_framework.renderers.JSONRenderer',
    # 'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
 ],

六、异常模块

1、所有经过drf的AIPView视图类产生的异常,都可以提供异常处理方案(包括三大认证);

2、drf默认提供了异常处理方案(rest_framework.views.exception_handler),但是

处理范围有限;

3、drf提供的处理方案两种,处理后的异常(一般都是前端出现的错误)返回异常现象,没有处理(一般都是服务器错误)返回None;

4、自定义异常的目的就是解决drf没有处理的异常,让前台得到合理的异常信息返回,后台记录异常的具体信息;

ps:ORM查询时的错误drf一般不自动处理.

'''
#异常模块:APIView类的dispatch方法中
request=self.handle_exception(exc)#点进去
#获取处理异常的句柄(方法)
#一层层看源码,走的是配置文件,拿到的是rest_framework.views的exception_handler
#自定义:直接写exceptiot_handler函数,在自己的配置文件配置EXCEPTION_HANDLER指向自己写的
exception_handler = self.get_exception_handler()
#异常处理的结果
#自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response一定有值
response= exception_handler(exc,context)
'''
# 一定要在settings文件中将异常模块配置自己的异常处理函数
#settings中配置:
REST_FRAMEWORK = {
    # 全局配置异常模块
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',  # api为应用名
}
#自定义异常处理py文件
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response

# 先交个drf处理客户端异常,如果结果response为None代表服务器异常,自己处理
# 最终一定要在日志文件中记录异常现象
def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
    detail = '%s - %s - %s' % (context.get('view'), context.get('request').method, exc)
    if not response:  # 服务端错误
        response =  Response({'detail': detail})
    else:
        response.data = {'detail': detail}

    # 核心:要将response.data.get('detail')信息记录到日志文件
    # logger.waring(response.data.get('detail'))

    return response

猜你喜欢

转载自www.cnblogs.com/mqhpy/p/12093329.html