zoukankan      html  css  js  c++  java
  • Django解析器

    1.什么是解析器?

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

      安装与使用:(官方文档)

      https://www.django-rest-framework.org/ 

    pip install djangorestframework
     1 from rest_framewirk.views import APIView
     2 class UsersView(APIView):
     3     def get(self,request,*args,**kwargs):
     4 
     5         return Response('...')
     6 
     7     def post(self,request,*args,**kwargs):
     8         # # application/json
     9         # print(request._request.body) # b"xxxxx"   decode()   json.loads
    10         # print(request._request.POST) # 无
    11         # 当post 请求的数据格式是application/json的时候, request._request.body有值,而request._request.POST并没有值
    12         # 我们要通过 decode + json.loads 来获取数据
    13         
    14         # # www-form-url-encode
    15         # print(request._request.body)
    16         # print(request._request.POST)
    17         # 当post 请求的数据格式是www-form-url-encode的时候,request._request.body和request._request.POST都有值
    18         
    19         
    20         # 而在我们用rest framework时往往发送的都是json格式的数据,那我们每次都要这么费事的转化吗,答案肯定不是
    21         # 可以设置     parser_classes
    22         
    23         from rest_framework.parsers import JSONParser,FormParser
    24         class UsersView(APIView):
    25             parser_classes = [JSONParser,FormParser]    #表示服务端可以解析的数据格式的种类。
    26             #如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据
    27             #如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据
    28 
    29             def get(self,request,*args,**kwargs):
    30                 return Response('...')
    31 
    32             def post(self,request,*args,**kwargs):
    33                 # request.data 就是 处理转化后的数据  {'name':'xxx','age':'12'}
    34                 print(request.data)
    35           print(request.FILES)
    36           print(request.POST)
    37           return Response('...')
    38 
    39       # 全局使用: 配置文件  一般都默认使用全局配置
    40         REST_FRAMEWORK = {
    41            'DEFAULT_PARSER_CLASSES':[
    42             'rest_framework.parsers.JSONParser',
    43             'rest_framework.parsers.FormParser',
    44            ]
    45         }

    2.print(request.data)的源码

     1 class Request(object):
     2     @property
     3     def data(self):
     4         if not _hasattr(self, '_full_data'):
     5        #调用_load_data_and_files方法
     6             self._load_data_and_files()
     7         return self._full_data
     8         
     9     def _load_data_and_files(self):
    10         if not _hasattr(self, '_data'):
    11        #调用_parse方法
    12             self._data, self._files = self._parse()
    13             
    14     def _parse(self):
    15      #调用DefaultContentNegotiation类的select_parser方法,见下面
    16         parser = self.negotiator.select_parser(self, self.parsers)       # 在封装Request的时候self.parser = 配置的解析类的对象列表
    17         #self.negotiator = self._default_negotiator() = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS()
    18         
    19         if not parser:
    20             #如果返回 None  说明不匹配,抛出异常
    21             raise exceptions.UnsupportedMediaType(media_type)
    22 
    23         try:
    24             # 匹配成功, 相应的解析类对象调用parse方法
    25             parsed = parser.parse(stream, media_type, self.parser_context)
    26         
    27 class DefaultContentNegotiation(BaseContentNegotiation):
    28     def select_parser(self, request, parsers):
    29         for parser in parsers:
    30             # 判断 解析类的对象和 请求的 content_type 是否匹配
    31             if media_type_matches(parser.media_type, request.content_type):
    32                 return parser
    33         return None 
    34         
    35         
    36 拿 JSONParser 举例
    37 class JSONParser(BaseParser):
    38     
    39     media_type = 'application/json'
    40     renderer_class = renderers.JSONRenderer
    41     strict = api_settings.STRICT_JSON
    42 
    43     def parse(self, stream, media_type=None, parser_context=None):
    44         try:          #和我们自己处理是一个原理
    45             # 先decode
    46             decoded_stream = codecs.getreader(encoding)(stream)
    47             parse_constant = json.strict_constant if self.strict else None
    48             # 再load
    49             return json.load(decoded_stream, parse_constant=parse_constant)
    50         except ValueError as exc:
    51             raise ParseError('JSON parse error - %s' % six.text_type(exc))
  • 相关阅读:
    PHP导出数据到淘宝助手CSV的方法分享
    创业日志:壹百款购物客户中心正式上线啦!
    THINKPHP+JS缩放图片式截图的实现
    入园3年来的感慨
    CentOS 5 全攻略 一步一步配置详解
    创业日记:进入电子商务领域,需未雨绸缪,更要步步谨慎
    IT商悟读书笔记
    震惊的事情一波接一波的,找自己的FREE
    创业日记:微团队,技术应用思考
    博客园我回来了!
  • 原文地址:https://www.cnblogs.com/qq849784670/p/10078515.html
Copyright © 2011-2022 走看看