CBV的源码分析
1
2 def dispatch(self, request, *args, **kwargs):
3 if request.method.lower() in self.http_method_names:
4 handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
5
6 else:
7 handler = self.http_method_not_allowed
8
9 return handler(request, *args, **kwargs)
drf之APIView的执行流程分析
1
2 makemigrations app01
3
4 @classmethod
5 def as_view(cls, **initkwargs):
6
7 view = super().as_view(**initkwargs)
8 return csrf_exempt(view)
9
10
11
12走View类的as_view方法中的小view函数
13 def view(request, *args, **kwargs):
14
15 self = cls(**initkwargs)
16 return self.dispatch(request, *args, **kwargs)
17
18
19
20 def dispatch(self, request, *args, **kwargs):
21
22 request = self.initialize_request(request, *args, **kwargs)
23 self.request = request
24
25 try:
26
27 self.initial(request, *args, **kwargs)
28
29 except Exception as exc:
30 response = self.handle_exception(exc)
31
32 self.response = self.finalize_response(request, response, *args, **kwargs)
33 return self.response
34
35 APIView做了三件事:
36 1. 把Django的request封装了新的request,drf的request
37 以后你在视图函数中,在使用request,就是新的request了。
38 2. 进行了三大认证:
39 self.perform_authentication(request)
40 self.check_permissions(request)
41 self.check_throttles(request)
42 3. 做了全局的异常处理
43
44
45 在执行视图函数之前,进行了三大认证。
drf的request对象分析
1
2def initialize_request(self, request, *args, **kwargs):
3 return Request(
4 request,
5 parsers=self.get_parsers(),
6 authenticators=self.get_authenticators(),
7 negotiator=self.get_content_negotiator(),
8 parser_context=parser_context
9 )
10
11
12
13class Request:
14 def __init__(self, request, parsers=None, authenticators=None,
15 negotiator=None, parser_context=None):
16 assert isinstance(request, HttpRequest), (
17 'The `request` argument must be an instance of '
18 '`django.http.HttpRequest`, not `{}.{}`.'
19 .format(request.__class__.__module__, request.__class__.__name__)
20 )
21
22 self._request = request
23
24
25是因为再Request类中定义了__getattr__方法
26 def __getattr__(self, attr):
27 try:
28 return getattr(self._request, attr)
29 except AttributeError:
30 return self.__getattribute__(attr)
31
32
33 多了一个data属性
34 针对post请求的三种编码格式都可以从data属性中取到
序列化类Seaializer的使用
1Django2默认支持以下5个转化器:
2
3str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
4int,匹配正整数,包含0。
5slug,匹配字母、数字以及横杠、下划线组成的字符串。
6uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
7path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)