zoukankan      html  css  js  c++  java
  • APIView分析

    APIView源码分析

    from rest_framework.views import APIView
    
    class BookAPIView(APIView):
        ...
        
    入口 urlpatterns = [
        url(r'^books/(d*)', views.BookAPIView.as_view()),
    ] as_view()
    
    
    @classmethod   # 类的绑定方法
    def as_view(cls, **initkwargs):
    
        ...
    
        view = super().as_view(**initkwargs) # 调用父类(View)中的as_view方法(也就是CBV中源码中的as_view方法)
        view.cls = cls
        view.initkwargs = initkwargs
        # 取消csrf认证(csrf装饰器)
        return csrf_exempt(view) # 相当于 return view
    # 当请求过来---》路由匹配上---》执行view(request)
    
    
    def view(request, *args, **kwargs):
        self = cls(**initkwargs) # 调用类的类名,这里就是BookAPIView,实列化对象。
        ...
    
        self.request = request
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)
        # 注意: 这里的self是BookAPIView实列化的对象,BookAPIView继承了APIView,所以这里调用的是APIView里的dispatch方法
    
    
    def dispatch(self, request, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        # 这里重新包装request对象
        request = self.initialize_request(request, *args, **kwargs)
        # 重新包装完request对象然后再复值给request
        self.request = request
        self.headers = self.default_response_headers  # deprecate?
    
        try:
            # 三大认证模块
            self.initial(request, *args, **kwargs)
            
            # 判断请求方法是否在http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']中
            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
    
    
    def initialize_request(self, request, *args, **kwargs):
    
        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
        )
    
    
    def initial(self, request, *args, **kwargs):
        self.format_kwarg = self.get_format_suffix(**kwargs)
    
        neg = self.perform_content_negotiation(request)
        request.accepted_renderer, request.accepted_media_type = neg
    
        version, scheme = self.determine_version(request, *args, **kwargs)
        request.version, request.versioning_scheme = version, scheme
    
        # 认证组件:校验用户 - 游客、合法用户、非法用户
        # 游客:代表校验通过,直接进入下一步校验(权限校验)
        # 合法用户:代表校验通过,将用户存储在request.user中,再进入下一步校验(权限校验)
        # 非法用户:代表校验失败,抛出异常,返回403权限异常结果
        self.perform_authentication(request)
    
        # 权限组件:校验用户权限 - 必须登录、所有用户、登录读写游客只读、自定义用户角色
        # 认证通过:可以进入下一步校验(频率认证)
        # 认证失败:抛出异常,返回403权限异常结果
        self.check_permissions(request)
    
        # 频率组件:限制视图接口被访问的频率次数 - 限制的条件(IP、id、唯一键)、频率周期时间(s、m、h)、频率的次数(3/s)
        # 没有达到限次:正常访问接口
        # 达到限次:限制时间内不能访问,限制时间达到后,可以重新访问
        self.check_throttles(request)
    
  • 相关阅读:
    linux库
    java实现第七届蓝桥杯路径之谜
    java实现第七届蓝桥杯路径之谜
    java实现第七届蓝桥杯路径之谜
    java实现第七届蓝桥杯打印数字
    java实现第七届蓝桥杯打印数字
    java实现第七届蓝桥杯打印数字
    java实现第七届蓝桥杯打印数字
    java实现第七届蓝桥杯七星填数
    java实现第七届蓝桥杯七星填数
  • 原文地址:https://www.cnblogs.com/chenwenyin/p/13405552.html
Copyright © 2011-2022 走看看