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('...')