zoukankan      html  css  js  c++  java
  • RestFramework之解析器

    一、什么是解析器?

      对请求的数据进行解析 - 请求体进行解析。 解析器在你不拿请求体数据时 不会调用。

      安装与使用:

      https://www.django-rest-framework.org/ 官方文档

      

    pip/pip3 install djangorestframework
    from rest_framewirk.views import APIView
    class
    UsersView(APIView): def get(self,request,*args,**kwargs): return Response('...') def post(self,request,*args,**kwargs): # # application/json # print(request._request.body) # b"xxxxx" decode() json.loads # print(request._request.POST) # 无 # 当post 请求的数据格式是application/json的时候, request._request.body有值,而request._request.POST并没有值 # 我们要通过 decode + json.loads 来获取数据 # # www-form-url-encode # print(request._request.body) # print(request._request.POST) # 当post 请求的数据格式是www-form-url-encode的时候,request._request.body和request._request.POST都有值 # 而在我们用rest framework时往往发送的都是json格式的数据,那我们每次都要这么费事的转化吗,答案肯定不是 # 可以设置 parser_classes from rest_framework.parsers import JSONParser,FormParser class UsersView(APIView): parser_classes = [JSONParser,FormParser] #表示服务端可以解析的数据格式的种类。 #如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据 #如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据 def get(self,request,*args,**kwargs): return Response('...') def post(self,request,*args,**kwargs): # request.data 就是 处理转化后的数据 {'name':'xxx','age':'12'} print(request.data)           print(request.FILES)           print(request.POST)          return Response('...')      # 全局使用: 配置文件 一般都默认使用全局配置         REST_FRAMEWORK = {        'DEFAULT_PARSER_CLASSES':[     'rest_framework.parsers.JSONParser',     'rest_framework.parsers.FormParser',         ]         }

    2.  print(request.data) 的 源码

      

    class Request(object):
        @property
        def data(self):
            if not _hasattr(self, '_full_data'):
           #调用_load_data_and_files方法
                self._load_data_and_files()
            return self._full_data
            
        def _load_data_and_files(self):
            if not _hasattr(self, '_data'):
           #调用_parse方法
                self._data, self._files = self._parse()
                
        def _parse(self):
         #调用DefaultContentNegotiation类的select_parser方法,见下面
            parser = self.negotiator.select_parser(self, self.parsers)       # 在封装Request的时候self.parser = 配置的解析类的对象列表
            #self.negotiator = self._default_negotiator() = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS()
            
            if not parser:
                #如果返回 None  说明不匹配,抛出异常
                raise exceptions.UnsupportedMediaType(media_type)
    
            try:
                # 匹配成功, 相应的解析类对象调用parse方法
                parsed = parser.parse(stream, media_type, self.parser_context)
            
    class DefaultContentNegotiation(BaseContentNegotiation):
        def select_parser(self, request, parsers):
            for parser in parsers:
                # 判断 解析类的对象和 请求的 content_type 是否匹配
                if media_type_matches(parser.media_type, request.content_type):
                    return parser
            return None 
            
            
    拿 JSONParser 举例
    class JSONParser(BaseParser):
        
        media_type = 'application/json'
        renderer_class = renderers.JSONRenderer
        strict = api_settings.STRICT_JSON
    
        def parse(self, stream, media_type=None, parser_context=None):
            try:          #和我们自己处理是一个原理
                # 先decode
                decoded_stream = codecs.getreader(encoding)(stream)
                parse_constant = json.strict_constant if self.strict else None
                # 再load
                return json.load(decoded_stream, parse_constant=parse_constant)
            except ValueError as exc:
                raise ParseError('JSON parse error - %s' % six.text_type(exc))
  • 相关阅读:
    20165339 预备作业3 Linux安装及学习
    20165339 学习基础和c语言基础调查
    20165339 我期望的师生关系
    2018-2019-1 20165332 《信息安全系统设计基础》第3周学习总结
    2018-2019-1 20165332 《信息安全系统设计基础》第2周学习总结
    2018-2019-1 20165332 《信息安全系统设计基础》第1周学习总结
    20165332 2017-2018-2《Java程序设计》课程总结
    20165332实验五 网络编程与安全
    20165332实验四 Android开发基础
    20165332第十周课下作业
  • 原文地址:https://www.cnblogs.com/qq631243523/p/10071652.html
Copyright © 2011-2022 走看看