一、简介
本篇文章主要介绍了drf中的request对象,涉及部分面向对象知识以及drf的request源码介绍
二、request对象
①属性
分析request对象,首先需要先掌握面向对象的部分知识点,由下面的代码引出
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
obj = Request(1, 2)
print(obj._request)
print(obj.xx)
显然输出为
1
2
如果此时在Requst类中添加__getattribute__方法,如:
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
def __getattribute__(self, item): # 新增部分
print("执行__getattribute__", item)
return 123
obj = Request(1, 2)
print(obj._request)
print(obj.xx)
此时的输出为
执行__getattribute__ _request
123
执行__getattribute__ xx
123
这样的原因是因为获取对象中的成员时,本质上会调用 __getattribute__
方法,默认我们不定义就用父类中的,而这里我们已经定义了,所以会调用我们自定义的__getattribute__方法。
因此如果想要正常返回的话,代码可以修改如下
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
def __getattribute__(self, item):
return super().__getattribute__(item)
obj = Request(1, 2)
print(obj._request)
print(obj.xx)
使用父类也就是object中的__getattribute__方法,即可获取到obj中存入的_request成员和xx成员
此时的输出为
1
2
如果此时在Requst类中添加__getattr__方法,如:
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
def __getattribute__(self, item):
return super().__getattribute__(item)
def __getattr__(self, item): # 新增部分
print("__getattr__", item)
return 999
obj = Request(1, 2)
print(obj._request)
print(obj.xx)
print(obj.v1)
此时的输出为
1
2
__getattr__ v1
999
这样的原因是当我们获取对象中不存在成员 时,会调用 __getattr__
方法。因此访问对象中不存在的v1成员时,便会执行__getattr__方法
②对象封装
下面假设django的request为HttpRequest类,而drf的request为Request类
class HttpRequest(object):
def __init__(self):
pass
def v1(self):
print("v1")
def v2(self):
print("v2")
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
request = HttpRequest()
request.v1()
request.v2()
request = Request(request, 111) # 将django中的request对象作为参数传入drf中
request._request.v1() # request._request即django中的request对象
request._request.v2()
此时的输出为:
v1
v2
v1
v2
结合前面的面向对象知识,如果想要调用django的request对象中的成员时,只用写request.xx,即可将代码修改如下:
class HttpRequest(object):
def __init__(self):
pass
def v1(self):
print("v1")
def v2(self):
print("v2")
class Request(object):
def __init__(self, req, xx):
self._request = req
self.xx = xx
"""
编写__getattr__方法,当调用drf中的不存在的成员时,
便去django中的request对象中寻找
"""
def __getattr__(self, attr):
try:
# self._request即django的request
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
request = HttpRequest()
request.v1()
request.v2()
request = Request(request, 111)
request.v1()
request.v2()
此时的输出为:
v1
v2
v1
v2
三、总结
drf中的request其实是对请求的再次封装,其目的就是在原来的request对象基础中再进行封装一些drf中需要用到的值。