Django解析器

1.什麼是解析器?django

  對請求的數據進行解析-請求體進行解析。解析器在你不拿請求體數據時,不會被調用。json

  安裝與使用:(官方文檔)api

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

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)的源碼post

 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))
相關文章
相關標籤/搜索