1)drf给咱们配置了多种解析数据包方式的解析类json
2)咱们能够经过配置来控制前台提交的数据,肯定哪些格式的数据须要在后台解析,哪些数据不解析api
3)全局配置就是针对每个视图类,局部配置就是针对指定的视图来,让它们能够按照配置规则选择性解析数据。服务器
1)先进入到APIView类的dispatch方法中(源码入口)。网络
2)从request = self.initialize_request(request, *args, **kwargs)中进去,获取解析类函数
3)从parsers=self.get_parsers()中进去, 去类属性(局部配置) 或 配置文件(全局配置) 拿 parser_classes源码分析
1 # 自定义drf配置 - 全局配置 2 REST_FRAMEWORK = { 3 'DEFAULT_RENDERER_CLASSES': [ 4 'rest_framework.renderers.JSONRenderer', 5 'rest_framework.renderers.BrowsableAPIRenderer', 6 ], 7 # 全局解析类配置 8 'DEFAULT_PARSER_CLASSES': [ 9 'rest_framework.parsers.JSONParser', # json数据包 10 'rest_framework.parsers.FormParser', # urlencoding数据包 11 'rest_framework.parsers.MultiPartParser' # form-date数据包 12 ], 13 # 全局配置异常模块 14 'EXCEPTION_HANDLER': 'api.exception.exception_handler', 15 }
from rest_framework.parsers import JSONParser class Book(APIView): parser_classes = [JSONParser] # 局部解析类配置,只有json类型的数据包才能被解析 def get(self, request, *args, **kwargs): # get方法 pk = kwargs.get('pk') if pk: book_obj = models.Book.objects.get(pk=pk) return Response({ 'status': 0, # 状态码 'msg': 'ok', # 状态信息 'results': { 'title': book_obj.title, 'price': book_obj.price } }) return Response('get ok') def post(self, request, *args, **kwargs): # post方法 # url拼接参数:只有一种传参方式就是拼接参数 print(request.query_params) # 数据包参数:有三种传承方式,form-data、urlencoding、json print(request.data) return Response('post ok')
1)全部通过drf的APIView视图类产生的异常,均可以提供异常处理方案post
2)drf默认提供了异常处理方案(rest_framework.views.exception_handler),可是处理范围有限url
3)drf提供的处理方案两种,处理了返回异常现象,没处理返回None(后续就是服务器抛异常给前台)spa
4)自定义异常的目的:就是为了 解决drf没有处理的异常,让前台获得合理的异常信息返回,后台记录异常具体信息3d
1)先进入APIView类的dispatch方法中(源码入口)
2)获取处理异常的方法
一层层看源码,走的是配置文件,拿到的是rest_framework.views的exception_handler()
自定义:直接写exception_handler函数,在本身的配置文件配置EXCEPTION_HANDLER指向本身的
exception_handler = self.get_exception_handler()
3) 异常处理的结果
自定义异常就是提供exception_handler异常处理函数,处理的目的就是让response必定有值
response = exception_handler(exc, context)
1 # 修改本身的配置文件setting.py 2 REST_FRAMEWORK = { 3 # 全局配置异常模块 4 'EXCEPTION_HANDLER': 'api.exception.exception_handler', 5 }
# 1)先将异常处理交给rest_framework.views的exception_handler去处理 # 2)判断处理的结果(返回值)response,有值表明drf已经处理了,None表明须要本身处理 # 自定义异常处理文件exception,在文件中书写exception_handler函数 from rest_framework.views import exception_handler as drf_exception_handler from rest_framework.views import Response from rest_framework import status def exception_handler(exc, context): # drf的exception_handler作基础处理 response = drf_exception_handler(exc, context) # 为空,自定义二次处理 if response is None: # print(exc) # print(context) print('%s - %s - %s' % (context['view'], context['request'].method, exc)) return Response({ 'detail': '服务器错误' }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True) return response
1 from rest_framework.response import Response
2 def __init__(self, data=None, status=None, 3 template_name=None, headers=None, 4 exception=False, content_type=None): 5 """ 6 :param data: 响应数据 7 :param status: http响应状态码 8 :param template_name: drf也能够渲染页面,渲染的页面模板地址(不用了解) 9 :param headers: 响应头 10 :param exception: 是否异常了 11 :param content_type: 响应的数据格式(通常不用处理,响应头中带了,且默认是json) 12 """
1 # status就是解释一堆 数字 网络状态码的模块 2 from rest_framework import status 就是解释一堆 数字 网络状态码的模块 3 # 通常状况下只须要返回数据,status和headers都有默认值 4 return Response(data={数据}, status=status.HTTP_200_OK, headers={设置的响应头})