zoukankan      html  css  js  c++  java
  • python-django rest framework框架之解析器

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

    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))
  • 相关阅读:
    《RTC — RTC相关操作以及如何同步系统时间》
    《关闭服务器,再次启动服务器提示bind:address already in use》
    《海思中内存分配和优化》
    《开发板 — 查看共享内存情况》
    《通过himm读取指定引脚并保存在共享内存中》
    《开发板 — 格式化TF卡》
    《网络编程 — UDP》
    《网络编程 — 服务器中bind的ip地址是什么》
    《使用gdb中core dump》
    《 Linux套接字编程中的5个隐患 》
  • 原文地址:https://www.cnblogs.com/liuwei0824/p/8428310.html
Copyright © 2011-2022 走看看