首先得有一点常识,比如用户认证,就是authenticate
比如一个函数,应该有返回值,
比如一个类里面的self,真的是代表本身这个类吗
再比如看到一个东西加括号,就两种情况,一种是函数,一种是类,区分函数和类,就看加括号之后的东西,是否还调用属性或者方法
还有如果你用pycharm,看源码就很方便了,看到一个属性或方法,你需要做的就是按住ctrl点进去就行了
假设你已经知道,dispatch函数是源码的入口,然后我们就可以愉快的交流了
下面演示如何使用rest_framework的用户认证功能,以及为什么要这样做
1.写路由匹配
因为是cbv视图,所以用as_view()
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/', views.TestView.as_view()),
]
2.CBV风格视图
from django.shortcuts import HttpResponse
from rest_framework.views import APIView#导入rest_framework的试图类
class TestView(APIView):
self.dispatch #只是为了进源码
def get(self,request,*args,**kwargs):
return HttpResponse('ok')
好了,最基本的框架就这样搭好了,我们开始看源码,源码的入口是在 APIView 的dispatch方法,所以我们点进去
dispatch函数:
def dispatch(self, request, *args, **kwargs):#这是APIView类的入口
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
和Django的dispatch类似,但是增加了额外的钩子,比如开始,结束,以及异常的处理
"""
self.args = args #封装参数
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs) #重新封装了request
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
经过观察,这个函数里面,能让我们感觉有东西的地方就是重新封装request和self.initial初识化这两个地方
1.1先看重新封装request这个
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
返回初始化后的request
"""
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.2
def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes] #从配置读取用户认证配置,然后实例化,点进这个self.authentication_classes
这个函数返回了一个列表,通过列表生成式,循环 self.authentication_classes ,然后拿到的东西实例化
tips:看到一个东西加括号,就两种情况,一种是函数,一种是类,区分函数和类,就看加括号之后的东西,是否还调用属性或者方法
1.3
class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES #
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
坏了,这下不能点了,看settings,说明这是配置信息,好了,看request看到这就走不下去了,因为不能点了,现在我们拿到的信息是:
在封装request的时候, 把一个auth()列表传到了request的参数里面,然后这个auth()是从这个self.authentication_classes 里面拿到的