• rest-framework之APIView


    一、安装djangorestframework

    方式一:pip3 install djangorestframework
    
    方式二:pycharm图形化界面安装
    
    方式三:pycharm命令行下安装(装在当前工程所用的解释器下)


    djangorestframework:
        它是一个app,可以应用到项目中;
        快速的构建resful规范的接口;
        以后再执行的dispatch方法是APIView的dispatch方法;
    
    
    restframework提供了一个Request对象;
    Request对象继承了Django默认的HttpRequest对象,它最核心的功能就是请求数据都包含在request.data属性中,
    类似于Django的request.POST,但是request.data应用范围更广:
    
    1)request.data:返回解析之后的请求体数据,类似于Django中标准的request.POST和request.FILES属性。
    request.data包含了解析之后的文件和非文件数据,包含了对POST PUT PATCH请求方式解析后的数据,利用了
    REST Framework的parsers解析器,不仅支持表单类型数据,也支持json数据
    
    2)request.query_params:
        与Django标准的request.GET相同


    drf使用:

    在setting中配置,把rest_framework加入到app中:
    INSTALLED_APPS= [
        'rest_framework',
    ]
    
    以后再写视图,可以都写cbv,继承APIView:
    from rest_framework.views import  APIView
    class Books(APIView):
        pass


    二、APIView源码分析

    as_view方法:

    @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)


    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
            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


    initialize_request

    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
            )


    initial方法(内部调用认证,权限,频率)

    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)


    源码分析总结:

    继承了APIView 之后:
        -1 所有的请求都没有csrf的认证了
        -2 在APIView中as_view本质还是调用了父类的as_view(View的as_view)
        -3 as_view中调用dispatch  -----》这个dispatch是APIView的dispatch
    
    
    -APIVIew的dispatch方法:
        -1 对原生request对象做了一层包装(面向对象的封装),以后再用的request对象都新的request对象
        -2 在APIView中self.initial(request, *args, **kwargs),里面有频率控制,权限控制和认证相关
        -3 根据请求方法执行咱们写的视图类中的相应方法
            --视图类中方法的request对象,已经变成了封装后的request
    -Request类:
        -1 原生的request是self._request
        -2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式)
        -3 query_params 就是原生request的GET的数据
        -4 上传的文件是从FILES中取
        -5 (重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)
  • 相关阅读:
    mysql应用技巧
    Python httplib学习
    桌标相关知识
    行业百科知识--Github
    Ghost win7 系统安装(虚拟机)
    记一次pycharm和vscode因网络问题插件下载失败的问题
    Pydiction补全插件
    MS17-010远程溢出漏洞(CVE-2017-0143)
    shell快速入门
    Yarn架构
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/12503897.html
Copyright © 2020-2023  润新知