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的格式

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

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请求,响应内容')

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

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

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
 
 
 

 

posted @ 2020-07-23 10:34  w770762632  阅读(187)  评论(0编辑  收藏  举报