DRF Django REST framework 之 解析器(二)

引入

Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据,经过 decode ,然后 json 反序列化之后,也可以得到一个Python字典类型的数据。

但是,这种方式并不被推荐,因为已经有了非常优秀的第三方工具,那就是Django Rest framework的解析器组件。

解析器使用

使用方式非常简单,分为如下两步:

  •  from rest_framework.views import APIView 
  • 继承 APIView 
  • 直接使用 request.data 就可以获取Json数据

如果你只需要解析Json数据,不允许任何其他类型的数据请求,可以这样做:

  •  from rest_framework.parsers import JsonParser 
  • 给视图类定义一个 parser_classes 变量,值为列表类型 [JsonParser] 
  • 如果 parser_classes = [] , 那就不处理任何数据类型的请求了。
from django.shortcuts import render, HttpResponse

from rest_framework.views import APIView
from rest_framework.parsers import FormParser


class CourseView(APIView):
    parser_classes = [FormParser]
    def get(self, request):
        pass

    def post(self, request):
        # request是被DRF封装的新对象,基于django的request
        # request.data是一个property,用于对数据进行校验
        # request.data最后会找到self.parser_classes中的解析器
        # 来实现对数据进行解析
        data = request.data
        print(data)     # {"course_name": "高数", "description": "烧脑..."}
        return HttpResponse(data)

解析器请求流程

1. 路由层加载as_view()方法,url和视图函数之间的绑定关系建立。

 APIView 执行方式相同

2. 用户发起请求,www.xxx.com/course/    POST请求方式

class CourseView(APIView):
    parser_classes = [FormParser]
    def get(self, request):
        pass

    def post(self, request): # 执行
        # request是被DRF封装的新对象,基于django的request
        # request.data是一个property,用于对数据进行校验
        # request.data最后会找到self.parser_classes中的解析器
        # 来实现对数据进行解析
        data = request.data
        print(data)     # {"course_name": "高数", "description": "烧脑..."}
        return HttpResponse(data)

3. request.data 触发解析操作

  (1)在 APIView 中的重写了 request 对象,在该对象中找  request.data

  

  (2) 在 self.load_data_and_files() 中把解析之后的数据赋值给了 self._full_data

  

  (3) 执行 _parse() 方法, 返回解析之后的数据

  

   实例化 Request 对象时,传入了 parsers 

  

    get_parsers() 返回的是一个列表

  

   调用 parser_classes 属性

  

   api_settings 是个实例化对象,而且该对象中没有 DEFAULT_PARSER_CLASSES 属性,所以执行 __getattr__() 方法。

  

   perform_import() 方法

  

  以上是选择解析类的流程

posted @ 2019-12-10 17:33  Nolinked  阅读(747)  评论(0编辑  收藏  举报