DRF的request对象,不是原生Django的request对象了,是新创建的。
一、介绍两个魔法方法
-
__getattr__
-
当对象.成员,不存在时,就会触发__getattr__ 方法
-
-
__getattribute__
-
当对象.成员,(无论成员是否存在),都会触发__getattribute__方法
-
二、源码解析request对象创建
1、在视图执行过程中,drf的Request的对象实例化
def initialize_request(self, request, *args, **kwargs):
#解析器
parser_context = self.get_parser_context(request)
#返回drf的Request的实例对象
return Request(
request,#原生django的request对象
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),#[认证对象1,...]
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
2、Request:简化的源码
from rest_framework.request import Request
class Request:
@property
def data(self):
#获取请求体中的数据:不管是form-data 还是json,都统一在data中获取数据
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
def __getattr__(self, attr):
# self._request 是原生django的request对象
# 当drf的request.GET,drf的requets没有,就去原生django的request中调用
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
@property
def FILES(self):
#获取文件数据
if not _hasattr(self, '_files'):
self._load_data_and_files()
return self._files
@property
def query_params(self):
#获取查询字符串数据
return self._request.GET
- drf的request设计的妙处
- 解决了原生django只能处理urlencode 类型的数据,即表单类型的数据,无法原始的json格式数据
- 实现
__getattr__
魔法方法:当drf的request中没有的成员,就去django的request中获取- request.GET, 在drf的request中没有实现该方法,就触发魔法方法,去django的request中获取GET方法了