• $Django cbv源码分析 djangorestframework框架之APIView源码分析


    1 CBV的源码分析

    #视图
    class login (View):
        pass
    #路由
    url(r'^books/$', views.login.as_view())
    #阅读源码:
    #左侧工程栏--->设置图标-->点击--->show members(能看到py文件,pu下的类,类下的方法)
    -Class Base View(基于类的视图)
        -Function Base View(基于函数的视图)
        -def as_view 类方法 :返回view
        -def view:as_view的内的函数(闭包)
    -python中一切皆对象:函数也是对象 -hasattr(self, 'get')--判断self类中是不是有该(get)方法 -setattr(self,get,get_all):相当于把get函数,变成了get_all -getattr(self, 'get'):拿到get函数的内存地址 - def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs #执行:dispatch:谁的dispatch方法?写的cbv的那个c,视图中的那个视图类 #我这个类如果没有写dispatch,会执行View中的dispatch方法 return self.dispatch(request, *args, **kwargs) -def dispatch(self, request, *args, **kwargs): #request.method 前台请求的方法,转成了小写 #http_method_names View中定义的一个列表:是一堆请求方式 if request.method.lower() in self.http_method_names: #getattr的第三个参数是默认值:self.http_method_not_allowed #拿到get方法的内存地址 handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed #get(request,*args, **kwargs) return handler(request, *args, **kwargs

     总结:*******请求来了--->as_view---->view---->dispatch--->分发到不同的函数,执#行函数,拿到结果

     2 djangorestframework框架

       安装:djangorestframework
       -它是一个app,要在咱的项目中用
       -只是快速的构建resful规范的接口
       -csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用)
       -以后再执行的dispatch方法是APIView的dispatch方法
       -getattr和setattr
       重点掌握这三点:
        -request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面
        -request.query_params  这个是原来GET中的数据
        -request把原来的request包装进去了

    3  APIView源码分析

     @classmethod
        def as_view(cls, **initkwargs):
            """
            Store the original class on the view function.
    
            This allows us to discover information about the view when we do URL
            reverse lookups.  Used for breadcrumb generation.
            """
            if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
                def force_evaluation():
                    raise RuntimeError(
                        'Do not evaluate the `.queryset` attribute directly, '
                        'as the result will be cached and reused between requests. '
                        'Use `.all()` or call `.get_queryset()` instead.'
                    )
                cls.queryset._fetch_all = force_evaluation
    
            view = super(APIView, cls).as_view(**initkwargs)
            view.cls = cls
            view.initkwargs = initkwargs
    
            # Note: session based authentication is explicitly CSRF validated,
            # all other authentication is CSRF exempt.
            return csrf_exempt(view)
    as_view方法
    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
            request = self.initialize_request(request, *args, **kwargs)
            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
    dispatch
    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
            )
    initialize_request
    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.
            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)
    initial方法(内部调用认证,权限,频率)

     总结:*******请求来了--->as_view---->view---->dispatch(apiview的比上面的多做了  包了个request对象生成新的request对象  和调用initial方法 都是apiview自己的方法)--->分发到不同的函数,执#行函数,拿到结果

  • 相关阅读:
    几个常用排序的代码实现堆排序|快排|归并排序 Marathon
    0647回文子串 Marathon
    任意输入一个日期输出是当年的第几天星期几
    从输入URL到浏览器显示页面发生了什么
    常用链接整理
    computed 与 method
    将博客搬至CSDN
    leetcode_Two Sum
    VC++6.0与Office2010冲突解决方案
    C&C++_malloc函数
  • 原文地址:https://www.cnblogs.com/3sss-ss-s/p/10098371.html
Copyright © 2020-2023  润新知