rest-framework之解析器
解析器
解析器的作用
根据请求头 content-type 选择对应的解析器对请求体内容进行处理。
有application/json,x-www-form-urlencoded,form-data等格式
用来解析前台传过来的数据编码方式
urlencoded:form表单:name=lqz&age=18
formdata :上传文件:--dadfgdgag--
json:json格式 {"name":"lqz"}解析器取的顺序
- 视图类中取
- django总settings里取
- drf默认的配置文件取
全局配置解析器
全局配置
在setting中:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES':[
'rest_framework.parsers.JSONParser'
'rest_framework.parsers.FormParser'
'rest_framework.parsers.MultiPartParser'
]
}
路由:
urlpatterns = [
url(r'test/', TestView.as_view()),
]
视图函数:
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
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请求,响应内容')
- 局部使用:
在视图内部制定解析器名称
from rest_framework.parsers import JSONParser,MultiPartParser,FormParser
parser_classes = [JSONParser,FormParser]
class TestView(APIView):
a. 仅处理请求头content-type为application/json的请求体
parser_classes = [JSONParser, ]
b. 仅处理请求头content-type为application/x-www-form-urlencoded 的请求体
parser_classes = [FormParser, ]
c. 仅处理请求头content-type为multipart/form-data的请求体
parser_classes = [MultiPartParser, ]
d. 仅上传文件
parser_classes = [FileUploadParser, ]
e. 同时多个Parser
当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser
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请求,响应内容')
源码分析
在调用request.data时,才进行解析,由此入手
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
查看self._load_data_and_files()方法---->self._data, self._files = self._parse()
def _parse(self):
#用户请求头里content_type的值
media_type = self.content_type
#self.parsers 就是用户配置的parser_classes =[FileUploadParser,FormParser ]
#self里就有content_type,传入此函数
parser = self.negotiator.select_parser(self, self.parsers)
查看self.negotiator.select_parser(self, self.parsers)
def select_parser(self, request, parsers):
#同过media_type和request.content_type比较,来返回解析器,然后调用解析器的解析方法
#每个解析器都有media_type = 'multipart/form-data'属性
for parser in parsers:
if media_type_matches(parser.media_type, request.content_type):
return parser
return None
最终调用parser的解析方法来解析parsed = parser.parse(stream, media_type, self.parser_context)
Request实例化,parsers=self.get_parsers()
Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
get_parsers方法,循环实例化出self.parser_classes中类对象
def get_parsers(self):
return [parser() for parser in self.parser_classes]
self.parser_classes 先从类本身找,找不到去父类找即APIVIew 中的
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
api_settings是一个对象,对象里找DEFAULT_PARSER_CLASSES属性,找不到,会到getattr方法
def __getattr__(self, attr):
if attr not in self.defaults:
raise AttributeError("Invalid API setting: '%s'" % attr)
try:
#调用self.user_settings方法,返回一个字典,字典再取attr属性
val = self.user_settings[attr]
except KeyError:
# Fall back to defaults
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr)
# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val
user_settings方法 ,通过反射去setting配置文件里找REST_FRAMEWORK属性,找不到,返回空字典
@property
def user_settings(self):
if not hasattr(self, '_user_settings'):
self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
return self._user_settings
rest-framework之解析器的更多相关文章
- Django Rest framework 之 解析器
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- DRF Django REST framework 之 解析器(二)
引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...
- rest framework 之解析器
一.示例 1.api/urls.py from django.urls import path, re_path from api.views import UserView, ParserView ...
- Django Rest Framework之解析器
基本代码结构 urls.py: from django.conf.urls import url, include from web.views.s5_parser import TestView u ...
- Django REST framework的解析器与渲染器
解析器 解析器的作用 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 在了解解析器之前,我们要先知道Accept以及ContentTy ...
- django的rest framework框架——版本、解析器、序列化
一.rest framework的版本使用 1.版本可以写在URL中,通过GET传参,如 http://127.0.0.1:8082/api/users/?version=v1 (1)自定义类获取版本 ...
- Django高级篇三。restful的解析器,认证组件,权限组件
一.rest=framework之解析器 1)解析器作用. 根据提交的数据.只解析某些特定的数据.非法数据不接收,为了系统安全问题 比如解析的数据格式有 有application/json,x-www ...
- Django rest framework(5)----解析器
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Restful framework【第五篇】解析器
基本使用 -解析器 -源码从request.data -全局配置 -'DEFAULT_PARSER_CLASSES':['rest_framework.parsers.JSONParser'], -局 ...
- python-django rest framework框架之解析器
1.解析器 : 对请求的数据进行解析 - 请求体进行解析. 解析器在你不拿请求体数据时 不会调用. class UsersView(APIView): def get(self,request,*ar ...
随机推荐
- vue的一些注意点
每个 Vue 实例都会代理其 data 对象里所有的属性. 注意只有这些被代理的属性是响应的.如果在实例创建之后添加新的属性到实例上,它不会触发视图更新. 除了 data 属性,Vue实例暴露了一些有 ...
- UVA 2290 Transmitters
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- MySQL语法大全_自己整理的学习笔记(MySQL语句 整理二)
select * from emp; #注释 #--------------------------- #----命令行连接MySql--------- #启动mysql服务器 net start m ...
- k8s的基本使用
一.kubectl的命令参数 1)kubectl 能使用的命令.即查看帮助 [root@k8s6 ~]# kubectl kubectl controls the Kubernetes cluster ...
- 《Linux就该这么学》第十四天课程
samba服务的配置文件解读 samba服务解决了Linux系统与Windows系统之间的文件共享问题,是一个非常不错的服务 原创地址:https://www.linuxprobe.com/chapt ...
- 学习Acegi应用到实际项目中(9)- 实现FilterInvocationDefinition
在实际应用中,开发者有时需要将Web资源授权信息(角色与授权资源之间的定义)存放在RDBMS中,以便更好的管理.事实上,一般的企业应用都应当如此,因为这样可以使角色和Web资源的管理更灵活,更自由.那 ...
- eclipse 无法记住svn密码
每次要求输入密码,很恼人.经过一番折腾,在stackoverflow上找到了解决方案,上面大神果然多 简单的说,就是通过查看工作空间的日志文件,发现报了个java异常,缺少一个class文件(org. ...
- Runnable和Callable 的区别
Runnable和Callable 的区别 01.Runnable接口中只有一个run()没有返回值 没有声明异常 Callable接口中只有一个call()有返回值 有声明异常 02.Calla ...
- How to enable C development in a Windows 10 development environment VM
To enable C development in a Windows 10 development environment VM, follow these steps: Start VS in ...
- docker install
1.安装必要工具集 sudo yum install -y yum-utils 2.安装Docker官方源 sudo yum-config-manager \ --add-repo \ https:/ ...