Content-Type
爲 application/x-www-form-urlencoded
,纔去 request.body
中解析數據name=xi&age=18
form 表單提交默認會按照上面的兩種要求進行提交python
ajax 提交中的 data 數據雖然是字典格式,但默認也會把字典轉換成上面的數據格式再帶上請求頭進行提交ajax
若是 ajax 提交中指定 headers 爲 {'Content-Type': 'application/json'},那麼 body 有值,POST 無值django
若是 ajax 提交中指定 headers 爲 {'Content-Type': 'application/json'},且 data 的數據格式指定爲 JSON.stringfy(),那麼 body 有值,POST 無值,可是能夠到 request.body 中拿到 json 數據,轉成字符串類型,而後 json.loads(request.body) 便可獲取到字典類型的數據json
依靠請求頭 content-type
對用戶請求體中的數據進行解析,解析到 request.data
api
# demo\api\urls urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/parser/$', views.ParserView.as_view()), ]
# demo\api\views class ParserView(APIView): # 會讀取請求頭,JSONParser表示只能解析 content-type: application/json 頭 # FormParser表示只能解析 content-type: application/x-www-form-urlencoded 頭 parser_classes = [JSONParser, FormParser, ] def post(self, request, *args, **kwargs): ''' 容許用戶發送JSON格式數據 a. content-type: application/json b. {'name':'xi', 'age':18} ''' # 獲取解析後的結果,用的時候纔去解析,因此是代碼的起始位置 ''' 1. 獲取用戶的請求 2. 獲取用戶的請求體 3. 根據用戶請求頭和 parser_classes = [JSONParser, FormParser, ]中支持的請求頭進行比較 4. JSONParser對象去請求體 5. 賦值給 request.data 做爲處理後的結果 ''' print(request.data) return HttpResponse("ParserView")
經過 Request
找到 data
,data
中有 _load_data_and_files()
,裏面調用了 self._parse()
,self._parse()
中有 self.content_type
瀏覽器
圖片中 344 行,select_parser()
是選擇解析器,根據上面用戶提交的請求頭和所傳的 self.parsers
來找,parsers
就是前面 views.py
中所設置的 parser_classes = [JSONParser, FormParser, ]
,self
是請求相關的全部數據,即請求對象,它裏面有一個 contype_type
,是當前用戶的 content_type
。根據這兩個參數進行選擇服務器
選擇好解析器,執行解析器的 parse()
方法,若是選擇的是 JSONParser
解析器,就到 JSONParser
的 parse()
方法app
在 JSONParser
中執行 json.load()
方法,將 json
數據變爲字典類型post
上面的內容爲源碼的一部分,實際上流程的入口其實仍是從 dispatch
出發,對 request
進行封裝this
def get_parsers(self): """ Instantiates and returns the list of parsers that this view can use. """ # self.parser_classes 讀取的仍是 APIView 中的設置 return [parser() for parser in self.parser_classes]
因此請求剛進來時,全部 views.py
中所設置的 parser_classes = [JSONParser, FormParser, ]
解析器所有實例化成對象,也封裝到 request
中了。目前所學,Request
中有三種東西:封裝的 request
、認證的全部對象、解析器的全部對象,一樣,解析器也能夠進行全局配置
# demo\demo\settings.py REST_FRAMEWORK = { "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning", "DEFAULT_VERSION": 'v1', "ALLOWED_VERSION": ['v1', 'v2'], "VERSION_PARAM": 'version', "DEFAULT_PARSER_CLASSES": ["rest_framework.parsers.JSONParser", "rest_framework.parsers.FormParser"] }
# demo\api\views.py class ParserView(APIView): def post(self, request, *args, **kwargs): ''' 容許用戶發送JSON格式數據 a. content-type: application/json b. {'name':'xi', 'age':18} ''' # 獲取解析後的結果 print(request.data) return HttpResponse("ParserView")
*/*
表示任何類型,type/*
表示該類型下的全部子類型