drf之APIView的执行流程分析

CBV的源码分析

1   # 入口:path('index/', views.IndexView.as_view()),
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            # handler = getattr(self, 'get', self.http_method_not_allowed) # handler就是函数内存地址
6        else:
7            handler = self.http_method_not_allowed
8        # get, post, put ...
9        return handler(request, *args, **kwargs) # get(request, *args, **kwargs), post()

drf之APIView的执行流程分析

 1# 数据库迁移:
2    makemigrations app01 # 后面可以加应用名,代表只迁移这个应用下的数据
3# 如果不加应用名,代表迁移所有应用的数据
4    @classmethod
5    def as_view(cls, **initkwargs):
6         # View类的as_view()
7        view = super().as_view(**initkwargs) #view:是View里面的as_view里面的view的函数内存地址
8        return csrf_exempt(view) # 去掉了csrf的验证, 跟之前的加在视图函数上一毛一样
9
10
11# get请求来了,下一步怎么走?
12走View类的as_view方法中的小view函数
13 def view(request, *args, **kwargs):
14            # self 就是IndexView类的对象
15            self = cls(**initkwargs) # IndexView()
16            return self.dispatch(request, *args, **kwargs)
17
18
19# APIView的源码分析:
20    def dispatch(self, request, *args, **kwargs):
21        # 它封装了新的request, request还是Django的request
22        request = self.initialize_request(request, *args, **kwargs)
23        self.request = request  # drf的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    # 以后,只要继承了APIView, 在视图函数中使用的request都是新的request。
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 # 为什么新的request和老的request使用起来一模一样?
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  # 新的request有什么特性?
33    多了一个data属性
34    针对post请求的三种编码格式都可以从data属性中取到

序列化类Seaializer的使用

1Django2默认支持以下5个转化器:
2
3str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
4int,匹配正整数,包含0
5slug,匹配字母、数字以及横杠、下划线组成的字符串。
6uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
7path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
posted @ 2022-01-04 11:18  一叶松  阅读(64)  评论(0编辑  收藏  举报