这篇教程Django drf请求模块源码解析写得很实用,希望能帮到您。 DRF 框架,全称为 Django Rest Framework,是 Django 内置模块的扩展,用于创建标准化 RESTful API;它利用 ORM 映射数据库,并自定义序列化数据进行返回,多用于前后端分离项目 项目地址: https://github.com/encode/django-rest-framework 请求模块:request对象源码入口 APIView 类中dispatch 方法中的:request=self.iniialize_request(*args, **kwargs) ,源码如下:
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context ) 源码分析 源码很简单,第1句parser_context = self.get_parser_context(request) ,我们进入方法get_parser_context 查看源码: """Returns a dict that is passed through to Parser.parse(),as the `parser_context` keyword argument."""# Note: Additionally `request` and `encoding` will also be added# to the context by the Request object.return { 'view': self, 'args': getattr(self, 'args', ()), 'kwargs': getattr(self, 'kwargs', {})} 上面的代码的意思是:返回一个解析的字典以便于Parser.parse() 去解析,另外还通过Request 对象添加了上下文request 和encoding 第二句返回了一个Request 对象,点击进入查看 
我们可以分析出,内部对request 做了二次封装,_request 是一个HttpRequest 对象,并且Request 类中还有__getattr__ 此方法,代码如下: def __getattr__(self, attr): """ If an attribute does not exist on this instance, then we also attempt to proxy it to the underlying HttpRequest object. """ try: return getattr(self._request, attr) except AttributeError: return self.__getattribute__(attr) 意思是如果这个实例上不存在一个属性,那么我们也会尝试将其代理到底层HttpRequest 对象。接下来我们可以通过案例演示 案例演示 
我们创建了TestView 视图,视图函数中打印了3个request 属性,并且在response 上打了一个断点,接下来通过url 访问视图,进入断点如下, 
我们可以清楚的看到: - request是
drf 的Request 对象 - request下有
data 属性,query_params 属性,但是没有GET 属性 上面还有一个Protected Attributes 属性,里面包含了_request 属性 
我们可以看到_request 是WSGIHttpRequest 对象,所以它会有GET 属性,所以我们视图中打印的request.GET 实际上和request._request.GET 是一样的,因为request 没有GET 属性,所以它就会访问_request 中的GET 属性,最后我们查看打印结果,如下: <QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}> 同样的,POST 请求也是如此,我们在视图中添加POST 的请求方式,如下: def post(self, request, *args, **kwargs): print(request.POST) # 兼容 print(request._request.POST) # 二次封装 print(request.data) # 拓展,兼容性最强,3种请求方式都可以 return Response("drf post ok") 我们都知道提交数据一般有3种方式 - multipart/form-data
- application/x-www-form-urlencoded
- application/json
首先我们使用multipart/form-data 提交请求数据,并请求API 
我们查看pycharm 打印结果 <QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}> 可以看到multipart/form-data 这种请求方式,都能打印出来 接着我们使用application/x-www-form-urlencoded 提交请求数据,并请求API 
<QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}><QueryDict: {'a': ['1']}> 可以看到application/x-www-form-urlencoded 这种请求方式,都能打印出来 最后我们使用application/json 提交请求数据,并请求API 
可以看到application/json 这种请求方式,只有request.data 能打印出来 <QueryDict: {}><QueryDict: {}>{'a': 1} 所以request.data 兼容性最强 总结drf 对request 进行了二次封装,request._request 就是原生的WSGIRequest 原生request 的属性和方法都可以被drf 的request 对象直接访问(兼容)drf 请求的所有url 拼接参数均被解析到query_params 中,所有的数据包均被解析到data 中其中post 请求,request.data 的兼容性最强,能兼容前台传输的json 格式的数据 到此这篇关于Django(48)drf请求模块源码分析 的文章就介绍到这了,更多相关Django drf源码内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net! Python中OpenCV实现查找轮廓的实例 python图像处理基本操作总结(PIL库、Matplotlib及Numpy) |