首先一个请求会经过类视图的diapatch()方法,就以此方法为突破口,分析restFramework的认证系统。
先将类视图代码贴一下:
class Authentication(Object):
def authenticate(self, request):
# 内部进行验证,并返回一个元组
return (xx, xxx) # request.user, request.auth 最后会赋值给他俩
def authentication_header(self, request): # 这个必须写,不写就报错
pass
# 类视图
class ClassView(APIView):
authentication_classes = [Authentication, ]
def get(self, request, *args, **kwargs):
pass
def post(self, request, *args, **kwargs):
pass
-dispatch()源码:
为什么会执行dispatch()方法呢?因为只要是类视图,再urls.py中就会执行as_view()方法,restframework中的APIView类重写了as_view()方法,因为APIView是继承了django的View类,但是跟django上的as_view()差不多,APIView(View)下面有这样一行代码:view = super(APIView, cls).as_view(**initkwargs),其实就是调用APIView的父类的as_view()方法,其返回view()方法,源码如下:
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs) # 这里返回dispatch()
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
# 其他的先不管,这里对原request进行了封装,现在进入initialize_request看看发生了什么
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
-initialize_request()源码:
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request)
# 这个函数返回了Request类实列,再进入Request类看看
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
-Request类的构造函数:
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
新的request已经是Request类的实列了,其中传入了原生的request,authenticators认证器,其他的也不知道什么意思。
如果调用原生的request,要这样写:request._request,具体看Request()的构造函数
这个验证器是怎么回事呢?authenticators=self.get_authenticators()
看看get_authenticators()