zoukankan      html  css  js  c++  java
  • Django rest framework框架——APIview源码分析

    一、什么是rest

    REST其实是一种组织Web服务的架构,而并不是我们想象的那样是实现Web服务的一种新的技术,更没有要求一定要使用HTTP。其目标是为了创建具有良好扩展性的分布式系统。

    可用一句话总结:url用来唯一定位资源, 用http请求方式来区分用户对数据的操作方式。

    http://www.scienjus.com/my-restful-api-best-practices/

    rest下的url

                1. url的设计规范
             没有任何动词 不同的请求代表不同的功能 GET:
    127.0.0.1:9001/books/ # 获取所有数据 GET: 127.0.0.1:9001/books/{id} # 获取单条数据 POST: 127.0.0.1:9001/books/ # 增加数据 DELETE: 127.0.0.1:9001/books/{id} # 删除数据 PUT: 127.0.0.1:9001/books/{id} # 修改数据 2. 数据响应规范 GET: 127.0.0.1:9001/books/ # 返回[{}, {}, {}] GET: 127.0.0.1:9001/books/{id} # {} 单条数据 POST: 127.0.0.1:9001/books/ # {} 添加成功的数据 DELETE: 127.0.0.1:9001/books/{id} # "" 返回空 PUT: 127.0.0.1:9001/books/{id} # {} 更新后完整的数据 3. 错误处理 { "error": "message" }

    二、APIView源码分析

        
    class LoginView(APIView):
        def get(self, request):
            pass
            
        def post(self, request):
            request.data  # 新的request对象 @property
            return
    class APIView(View):
        @classmethod
        def as_view(cls, **initkwargs):
            pass
            super(APIView, cls).as_view(**initkwargs)
            
        def initialize_request(self, request, *args, **kwargs):
        
            from rest_framework.request import Request
    
            return Request(
                request,  # 原生request对象
                parsers=self.get_parsers(), #
                authenticators=self.get_authenticators(),
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
                
        def dispatch(self):
            pass
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            
        def get_parsers(self):
        
            return [parser() for parser in self.parser_classes]
    1. views.LoginView.as_view()
    2. LoginView里面没有as_view方法,到父类APIView去找
    3. 执行View里面的as_view()方法,返回view函数
    
    4. url和视图函数之间的绑定关系建立完毕 { "login": view},等待用户请求
    5. 接收到用户请求:login,到建立好的绑定关系里面执行对应的视图函数:view(request)
    6. 视图函数的执行结果是什么就返回给用户什么:self.dispatch(), self.dispatch()的执行结果是什么,就返回给用户什么
    7. 此时的self代表的是LoginView的实例化对象
    8. 开始找dispatch方法,self里面没有,LoginView里面也没有,在APIView里面有
    9. 开始执行APIView里面的dispatch
    10. 最后找到http方法(GET,POST,PUT,DELETE),根据请求类型查找(request.method.lower())
    11. 开始执行找到的方法(GET),self.get(), self此时代表LoginView的实例化对象
      11.1 假设接收到的是POST请求, 执行request.data
      11.2 根据分析,所有的解析工作都在request.data里面实现,且data是一个方法(被装饰后的)
      11.2 开始执行request.data
    
            @property
            def data(self):
                if not _hasattr(self, '_full_data'):
                    self._load_data_and_files()
                return self._full_data
       11.3 执行self._load_data_and_files
      11.4 执行self._data, self._files = self._parse()
      11.5 parser = self.negotiator.select_parser(self, self.parsers)
    
        11.5.1 开始找self.parsers
        11.5.2 self.get_parses()
          [ parse() for parse in self.parser_classes ]
        11.5.3 parser_classes = api_settings.DEFAULT_PARSER_CLASSES
        11.5.4 from rest_framework import api_settings
        11.5.5 api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
    
        11.5.6 class APISettings():pass
        11.5.7 找不到DEFAULT_PARSER_CLASSES,__getattr__
          'DEFAULT_PARSER_CLASSES': (
          'rest_framework.parsers.JSONParser',
          'rest_framework.parsers.FormParser',
          'rest_framework.parsers.MultiPartParser'
                            ),
        11.5.8 首先找程序的settings
        11.5.9 然后找rest_framework的settings
    
    11.6 self._data就是我们想要的数据
    11.7 DRF将self._data = data
    11.8 request.data
    
    12. 在LoginView里面找到了对应的方法,执行该方法,最后返回给用户
    
      - DRF的所有功能都是在as_view()和dispatch里面重写的
      - 而解析器组件在dispatch方法里面重写了,具体是在重新封装的Request对象里面
  • 相关阅读:
    使用工具自动生成Linq类文件
    DateTime.MinValue和MaxValue引发的异常
    C# AD 验证登陆
    HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
    清理sqlserver 2012 日志文件
    如何修改博客园插入代码的默认代码大小?
    hdu 1241:Oil Deposits(DFS)
    【2014年寒假日常记录表(2014.1.9—2.23,45天)】
    hdu 1016 Prime Ring Problem(DFS)
    蓝桥杯 历届试题 错误票据(水题,排序)
  • 原文地址:https://www.cnblogs.com/zwq-/p/10079449.html
Copyright © 2011-2022 走看看