rest_framework-解析器
解析器
解析器就是服务端写api, 对于前端用户发来的数据进行解析, 解析完之后拿到自己能用数据
本质就是请求体中的数据进行解析器
前戏: post请求过来之后, django的request.body一定有值, request.post不一定有值,如果想让request.post有值, 必须转为QueryDict类型的值.
1, urls.py
访问该url, 并提交post请求
print(type(request._request))
导入模块
from django.core.handlers.wsgi import WSGIRequest
最下面的POST
继续, 进入self._load_post_and_files()
POST有值, 请求头的要求
请求头要求: 如果请求头中的Content-Type: application/x-www-form-urlencoded, request.POST中才有值(去request.body中解析数据)
如果是"application/x-www-form-urlencoded" 这个请求头, 就把数据放在post里
POST有值, 数据格式要求:
name=alex&age=18&gender=男
form表单, ajax请求: 默认都是以上这种请求头和数据格式!!!
如果ajax请求设置请求头为json类型, 那么post则没值. body里有值.
原生的django解析器, 那么post则没值.body里有值
原生的django解析器: post有无值得情况
解析器 前戏: django:request.POST/ request.body 1, 请求头要求: Content-Type: application/x-www-form-urlencoded PS: 如果请求头中的Content-Type: application/x-www-form-urlencoded, request.POST中才有值(去request.body中解析数据). 2, 数据格式要求: name=alex&age=18&gender=男 如: a.form表提交 <form nethod...> input... </form> b. ajax提交 $.ajax({url: ..., type: POST, data: {name: alex, age=18}}) 情况一: $.ajax({url: ..., type: POST, headers: {"Content-Type": "application/json"}, data: {name: alex, age=18}}) 情况二: $ajax({url: ... type: post, headers: {"Content-Type": "application/json"}data: JSON.stringfy({name: alex, age=18})})
rest_framework解析器, 对请求提数据进行解析
JSONParser解析器
from rest_framework.parsers import JSONParser
允许用户发送json数据
a.content-type: application/json
b.{name: "alex", age: 18}
view.py
from rest_framework.parsers import JSONParser class ParserView(APIView): parser_classes = [JSONParser, ] def post(self, request, *args, **kwargs): return HttpResponse("ParserView")
打印接受的数据.
print(request.data)
post请求, 发送json数据
打印结果: 自动解析, 自己没有反序列化.
{"name": "Alex"}
该请求头不支持, JSONParser只支持content-type: application/json
要想支持这种请求头,
FormParser: 表示只能解析application/x-www-form-urlencoded
请求进来的时候, 什么时候调用解析器?
request.data触发了解析器: 解析流程
1, 请求信息都在Request.data里
from rest_framework.request import Request
2, data
3, 解析:
4, 拿到所有解析器列表, 用户请求头
parsers: parser_classes = [JSONParser, FormParser, ]
self, 请求对象, self.content_type
parser = self.negotiator.select_parser(self, self.parsers)
5, 点击进入negotiator
6, 在APIView中, 进行initial的时候, request被重新封装了,
进入get_content_negotiator()
还是老套路, 获取到配置项中的每个类, 进行实例化.
7, 循环解析器列表, 取每个解析器支持的请求头 , 根据解析器支持的请求头, 返回到底应该用哪个解析器!!!
点击进入select_parser
例如找到JSONParser解析器.将请求数据解析
配置解析器
"DEFAULT_PARSER_CLASSES" : ["rest_framework.parsers.JSONParser", "rest_framework.parsers.FormParser"]
如果某个视图仅仅文件上传, 视图就需要单独设置解析器 局部配置解析器.
# parser_class = [JSONParser, FormParser]