Django rest_framework(DRF),学完之后,明显感觉自己对于Django的认知又拔高了一个level。
具体体现在以下几个方面,对于整个web开发的流程有了完整的认识,对于django各个组件以及组件之间的结合有了更深的体会。
DRF的关键就在于一个点上——APIView类下面的dispatch方法
def dispatch(self, request, *args, **kwargs): """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs # 1)对原生request进行了封装 request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: # 2)对前端的请求增加的3个限制,认证、权限、频率 self.initial(request, *args, **kwargs) # Get the appropriate handler method if request.method.lower() in self.http_method_names: # 3)通过反射执行“get/post/put/delete”函数 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) # 4)将返回的数据封装进自己提供的页面中 self.response = self.finalize_response(request, response, *args, **kwargs) return self.response <wiz_code_mirror>
32
1
def dispatch(self, request, *args, **kwargs):
2
"""
3
`.dispatch()` is pretty much the same as Django's regular dispatch,
4
but with extra hooks for startup, finalize, and exception handling.
5
"""
6
self.args = args
7
self.kwargs = kwargs
8
# 1)对原生request进行了封装
9
request = self.initialize_request(request, *args, **kwargs)
10
self.request = request
11
self.headers = self.default_response_headers # deprecate?
12
13
try:
14
# 2)对前端的请求增加的3个限制,认证、权限、频率
15
self.initial(request, *args, **kwargs)
16
17
# Get the appropriate handler method
18
if request.method.lower() in self.http_method_names:
19
# 3)通过反射执行“get/post/put/delete”函数
20
handler = getattr(self, request.method.lower(),
21
self.http_method_not_allowed)
22
else:
23
handler = self.http_method_not_allowed
24
25
response = handler(request, *args, **kwargs)
26
27
except Exception as exc:
28
response = self.handle_exception(exc)
29
# 4)将返回的数据封装进自己提供的页面中
30
self.response = self.finalize_response(request, response, *args, **kwargs)
31
return self.response
32
1)先看看对request做了那些操作
![](index_files/3b69fba4-93ab-422d-aa33-3246bce70625.png)
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 # 对应上面的,如果数据解析通过,将数据打包成字典供view用 )<wiz_code_mirror>
13
1
def initialize_request(self, request, *args, **kwargs):
2
"""
3
Returns the initial request object.
4
"""
5
parser_context = self.get_parser_context(request)
6
7
return Request(
8
request,
9
parsers=self.get_parsers(), # 首先获取到解析器,限制前端数据的请求与发送方式
10
authenticators=self.get_authenticators(), # 获取认证信息
11
negotiator=self.get_content_negotiator(), # 获取默认的异常处理信息
12
parser_context=parser_context # 对应上面的,如果数据解析通过,将数据打包成字典供view用
13
)
![](index_files/8fa6b4c9-7e86-4a84-8eb6-827e711a1a8d.png)
![](index_files/b7e8a943-841b-43eb-af9a-8b7a716a2980.png)
结论:从Request()类中的参数就可以看出Request()类在实例化的过程会对request中的数据进行认证、解析等限制。DRF的解析组件、认证组件的功能就用在了这里!此外还做了什么其实通过Request()类中的属性和方法就已经能知道个所以然了!
![](index_files/c92bc469-d39c-4457-aca9-cf2b5e8cce61.png)
2)紧接着又做了3个限制。(认证、权限、频率的调用)
![](index_files/a233d42c-43ee-4f3d-ab3a-a5644fc1f5d2.png)
def initial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """ self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. # 如果使用版本控制,则确定API版本。 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted # 三个限制组件在这里执行 self.perform_authentication(request) self.check_permissions(request) self.check_throttles(request)<wiz_code_mirror>
20
1
def initial(self, request, *args, **kwargs):
2
"""
3
Runs anything that needs to occur prior to calling the method handler.
4
"""
5
self.format_kwarg = self.get_format_suffix(**kwargs)
6
7
# Perform content negotiation and store the accepted info on the request
8
neg = self.perform_content_negotiation(request)
9
request.accepted_renderer, request.accepted_media_type = neg
10
11
# Determine the API version, if versioning is in use.
12
# 如果使用版本控制,则确定API版本。
13
version, scheme = self.determine_version(request, *args, **kwargs)
14
request.version, request.versioning_scheme = version, scheme
15
16
# Ensure that the incoming request is permitted
17
# 三个限制组件在这里执行
18
self.perform_authentication(request)
19
self.check_permissions(request)
20
self.check_throttles(request)
![](index_files/abeebb0a-2245-4ba4-8fe4-b866ff22c6a4.png)
def perform_authentication(self, request): """ Perform authentication on the incoming request. Note that if you override this and simply 'pass', then authentication will instead be performed lazily, the first time either `request.user` or `request.auth` is accessed. """ request.user # 这个地方不要懵逼了,其实是执行Request()里面的user()方法<wiz_code_mirror>
x
1
def perform_authentication(self, request):
2
"""
3
Perform authentication on the incoming request.
4
5
Note that if you override this and simply 'pass', then authentication
6
will instead be performed lazily, the first time either
7
`request.user` or `request.auth` is accessed.
8
"""
9
request.user # 这个地方不要懵逼了,其实是执行Request()里面的user()方法
回到Request()类中来
![](index_files/b90eb560-19d8-42ec-8d59-7523cd8c7b91.png)
其他的三个都一样的,没啥好说的了!
3)执行序列化组件了,分发路由,没啥好说的!
4)最后调用Responce响应器。就是返回DRF为我们提供的一个响应页面!
总结:
dispatch( )的执行其实就把DRF提供的十个组件轮一遍的过程,也就是对于前端的请求进行了限制、加工到做出响应的过程!
DRF源码展现了python类的封装、继承、派生、等有意思的玩法,里面有大量的python风格的代码!读明白之后会觉得非常有乐趣!