返回顶部

DRF之解析器

一. DRF解析器

  解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己想要的数据类型的过程。本质就是对请求体中的数据进行解析

  在了解解析器之前~大家要先知道Accept以及ContentType请求头。

  Accept是告诉对方我能解析什么样的数据,通常也可以表示我想要什么样的数据。

  ContentType是告诉对方我给你的是什么样的数据类型。

  那大家想一下,解析器工作原理的本质应该是什么?

  就是拿到请求的ContentType来判断前端给我的数据类型是什么,然后我们去拿相应的解析器去解析数据。

1. Django的解析器

源码通过request.POST进来后:

 

 

  

  application/x-www-form-urlencoded不是不能上传文件,是只能上传文本格式的文件,

  multipart/form-data是将文件以二进制的形式上传,这样可以实现多种类型的文件上传

  一个解析到request.POST,   request.FILES中

 

2.DRF的解析器

 

 

 

 

 

 

 

 

 

 

循环我们配置的每个解析器,得到他们的实例化对象

 

 

 

 

 

 

 

 也就是说我们的DRF支持Json,Form表单的请求,包括多种文件类型的数据。

视图中可以这么配置,默认就是这三种,其实也可以不配置。

 

 

 

 

3. 关于Django和DRF解析json数据的处理方式

假如前端通过ajax给我们发送json格式的数据:

<div>
        <form>
            {% csrf_token %}
            <p>用户名: <input type="text" id="user"></p>
            <p>密码: <input type="password" id="pwd"></p>
            <input type="button" id="login_btn" value="登录">
        </form>
    </div>
    <script src="{% static 'jquery.js' %}"></script>
    <script src="{% static 'jquery.cookie.js' %}"></script>
    <script>
        $('#login_btn').click(function () {

            var params = JSON.stringify({
                user: $('#user').val(),
                pwd: $('#pwd').val(),
            });
            $.ajax({
                url:"http://127.0.0.1:8000/parse/test/",
                type: 'post',
                contentType: "application/json",
                headers:{
                    "X-CSRFToken": $.cookie('csrftoken'),
                },
                data: params,
                success:function (data) {

                    console.log(data);
                }

            })

        })

    </script>

对于一般FBV来说:需要手动json.loads反序列一下,才能得到字典数据。POST中是没有值的,应为Django没有办法帮助我们自动解析json格式的数据.

只有自己从request.body中手动解析。

def index(request):

    if request.method == 'POST':
        # print(request.body)
        # print(request.POST)
        # user = request.POST.get('user')  # NONE
        # print(user)
        data = json.loads(request.body)
        user = data['user']
        print(user)

        return HttpResponse('..')
    else:
        return render(request, 'login.html')

对于django的CBV来说:需要手动json.loads反序列一下,才能得到字典数据。和上面一样。

class ParseView(View):

    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):
        # dict1 = {'k1':1}
        print("request.body:", request.body)
        print("request.POST:", request.POST)
        print("POST中拿数据:",request.POST.get('user'))
        print("body中拿数据:",json.loads(request.body).get('user'))
        # print("request.data:", request.data, type(request.data))

        # 如果你就是不使用JsonResponse的话,也可以给HttpResponse添加一个参数,content_type='application/json',
        # 那么前端ajax拿到数据之后,也是不需要反序列化的,ajax的回调函数就收到的就是一个反序列化之后的一个对象,因为ajax接受到数据后,
        # 通过这个data_type或者content_type发现你发送来的是个json格式的数据,那么ajax内容就自动将这个数据反序列化得到了js的数据对象,
        # 然后通过对象可以直接操作数据。
        # return HttpResponse(json.dumps(dict1), content_type='json')
        return HttpResponse('...')

 

对于DRF来说:前端发送过来的json数据,我们直接通过request.data就可以获取到了。

class ParseView(APIView):

    # parser_classes = [JSONParser, FormParser,MultiPartParser]

    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):

        print("data中拿数据:",request.data)
        
        return HttpResponse('...')

 

 

 

posted @ 2020-10-15 10:34  muguangrui  阅读(210)  评论(0编辑  收藏  举报