Django Rest framework 之 解析器


一、前言

在前端向后台发送form表单或者ajax数据的时候,django的content_type会拿到请求头中的Content-Type属性然后根据值进行解析。
将request.data中的值放到request.POST中需要满足两个条件

  • 请求头要求:
    Content-Type: application/x-www-form-urlencoded
    PS: 如果请求头中的 Content-Type: application/x-www-form-urlencoded,request.POST中才有值(去request.body中解析数据)。
  • 数据格式要求:
    name=weilan&age=18&gender=男

1、表单提交

form表单提交时会自动的将请求头中的Content-Type: application/x-www-form-urlencoded,数据也会自动转换为?parser=xxx&parser2=xxx的格式

>

2、ajax提交

默认的请求头中Content-Type: application/x-www-form-urlencoded

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

情况一:

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

情况二:

    $.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)

二、实例

1、仅处理请求头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请求,响应内容')

2、仅处理请求头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

3、 仅处理请求头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请求,响应内容')




    
    Title


upload.html

4、仅上传文件

#!/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



    
    Title


upload.html

6、 同时多个Parser

当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser

#!/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

5、全局配置

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

}

settings.py