Django Rest framework 之 解析器

1、前言

在前端向後臺發送form表單或者ajax數據的時候,django的content_type會拿到請求頭中的Content-Type屬性而後根據值進行解析。
將request.data中的值放到request.POST中須要知足兩個條件html

  • 請求頭要求:
    Content-Type: application/x-www-form-urlencoded
    PS: 若是請求頭中的 Content-Type: application/x-www-form-urlencoded,request.POST中才有值(去request.body中解析數據)。
  • 數據格式要求:
    name=weilan&age=18&gender=男

一、表單提交

form表單提交時會自動的將請求頭中的Content-Type: application/x-www-form-urlencoded,數據也會自動轉換爲?parser=xxx&parser2=xxx的格式前端

<form action="/api/parser/" method="post">
        <input type="text" name="parser"/>
        <input type="text" name="parser2"/>
        <input type="submit"/>
</form>>

二、ajax提交

默認的請求頭中Content-Type: application/x-www-form-urlencodedpython

$.ajax({
    url:...
    type:POST,
    data:{name:alex,age=18} # 內部轉化 name=weilan&age=18&gender=男
})

狀況一:ajax

$.ajax({
        url:...
        type:POST,
        headers:{'Content-Type':"application/json"}
        data:{name:weilan,age=18} # 內部轉化 name=weilan&age=18&gender=男
    })
    # body有值;POST無

狀況二:django

$.ajax({
        url:...
        type:POST,
        headers:{'Content-Type':"application/json"}
        data:JSON.stringfy({name:weilan,age=18}) # {name:weilan,age:18...} # 不在作內部轉換,而是傳遞字符串
    })
    # body有值;POST無
    # 這種狀況下request.body有值, 須要字節類型轉換成字符串類型。
    # json.loads(request.body)

2、實例

一、僅處理請求頭content-type爲application/json的請求體

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser


class TestView(APIView):
    parser_classes = [JSONParser, ]  # 解析類

    def post(self, request, *args, **kwargs):
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)

        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)

        return Response('POST請求,響應內容')

二、僅處理請求頭content-type爲application/x-www-form-urlencoded 的請求體

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FormParser


class TestView(APIView):
    parser_classes = [FormParser, ]

    def post(self, request, *args, **kwargs):
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)

        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)

        return Response('POST請求,響應內容')

views.py

三、 僅處理請求頭content-type爲multipart/form-data的請求體

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import MultiPartParser


class TestView(APIView):
    parser_classes = [MultiPartParser, ]

    def post(self, request, *args, **kwargs):
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST請求,響應內容')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
    <input type="text" name="user" />
    <input type="file" name="img">

    <input type="submit" value="提交">

</form>
</body>
</html>

upload.html

四、僅上傳文件

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import FileUploadParser


class TestView(APIView):
    parser_classes = [FileUploadParser, ]

    def post(self, request, filename, *args, **kwargs):
        print(filename)
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')

views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
    <input type="text" name="user" />
    <input type="file" name="img">

    <input type="submit" value="提交">

</form>
</body>
</html>

upload.html

六、 同時多個Parser

當同時使用多個parser時,rest framework會根據請求頭content-type自動進行比對,並使用對應parserjson

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser


class TestView(APIView):
    parser_classes = [JSONParser, FormParser, MultiPartParser, ]

    def post(self, request, *args, **kwargs):
        print(request.content_type)

        # 獲取請求的值,並使用對應的JSONParser進行處理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST請求,響應內容')

    def put(self, request, *args, **kwargs):
        return Response('PUT請求,響應內容')

views.py

五、全局配置

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser'
        'rest_framework.parsers.FormParser'
        'rest_framework.parsers.MultiPartParser'
    ]

}

settings.py
相關文章
相關標籤/搜索