zoukankan      html  css  js  c++  java
  • FBV CBV

    目录

      CBV 和 FBV 介绍

      1. 路由绑定

        urlpatterns = [
            # 1)项目启动,将test函数地址绑定给/test/路由
            # 2)请求/test/访问后台,后台就会调用绑定的test函数
            url(r'^test/$', views.test),
            
            # 1)项目启动,将as_view()函数执行结果返回的view函数地址绑定给/test/路由
            # 2)请求/test/访问后台,后台就会调用绑定的view函数
            # 3)view函数会将请求交给dispatch方法完成分发,分发(反射)给视图类的不同方法处理请求
            url(r'^test/$', views.Test.as_view()),
        ]
        
      2. 业务处理

        • fbv 每一个接口都会对应一个函数来响应请求

        • cbv 可以将一个资源的增删改查所有操放在一个类中管理,在内部再分方法逐一处理

          (高内聚低耦合:六个接口和一个类有关,但都能在类内部处理)

      三个View其实是同一个类
      继承View的目的:
      	i)继承as_view()方法,完成路由的配置
      	ii)继承dispath()方法,完成请求分发
      	注:如果自己写as_view()和dispath()方法,自定义视图类可以不用继承任何类的
      from django.http import JsonResponse
      from django.views import View
      from django.views.generic import View
      from django.views.generic.base import View
      class Test(View):  
          def get(self, request, *args, **kwargs):
              return JsonResponse('cbv ok', safe=False)
      

      django 的类视图拥有自动查找指定方法的功能, 通过调用是通过as_view()方法实现

      urls.py

      from meduo_mall.demo import views
      
      urlpatterns = [
          url(r'register/$', views.Demo.as_view())
      ]
      

      views.py

      from django.views.generic import View
      
      
      class Demo(View):
      
          def get(self, request):
              return HttpResponse('get page')
      
          def post(self, request):
              return HttpResponse('post page')
      

      为什么as_view能自动匹配指定的方法

      先看源码

          @classonlymethod
          def as_view(cls, **initkwargs):  # 实际上是一个闭包  返回 view函数
              """
              Main entry point for a request-response process.
              """
              for key in initkwargs:
                  if key in cls.http_method_names:
                      raise TypeError("You tried to pass in the %s method name as a "
                                      "keyword argument to %s(). Don't do that."
                                      % (key, cls.__name__))
                  if not hasattr(cls, key):
                      raise TypeError("%s() received an invalid keyword %r. as_view "
                                      "only accepts arguments that are already "
                                      "attributes of the class." % (cls.__name__, key))
      
              def view(request, *args, **kwargs):  # 作用:增加属性, 调用dispatch方法 
                  self = cls(**initkwargs)  # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
                  if hasattr(self, 'get') and not hasattr(self, 'head'):
                      self.head = self.get
                  self.request = request  # 为对象增加 request, args, kwargs 三个属性
                  self.args = args
                  self.kwargs = kwargs
                  return self.dispatch(request, *args, **kwargs)  # 找到指定的请求方法, 并调用它
              view.view_class = cls
              view.view_initkwargs = initkwargs
      
              # take name and docstring from class
              update_wrapper(view, cls, updated=())
      
              # and possible attributes set by decorators
              # like csrf_exempt from dispatch
              update_wrapper(view, cls.dispatch, assigned=())
              return view
      
          def dispatch(self, request, *args, **kwargs):
              # Try to dispatch to the right method; if a method doesn't exist,
              if request.method.lower() in self.http_method_names:  # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
                  handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出该方法
              else:
                  handler = self.http_method_not_allowed
              return handler(request, *args, **kwargs)  # 执行该方法
      
      

      简化版

          @classonlymethod
          def as_view(cls, **initkwargs):  # 实际上是一个闭包  返回 view函数
              """
              Main entry point for a request-response process.
              """
              def view(request, *args, **kwargs):  # 作用:增加属性, 调用dispatch方法 
                  self = cls(**initkwargs)  # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
                  if hasattr(self, 'get') and not hasattr(self, 'head'):
                      self.head = self.get
                  self.request = request  # 为对象增加 request, args, kwargs 三个属性
                  self.args = args
                  self.kwargs = kwargs
                  return self.dispatch(request, *args, **kwargs)  # 找到指定的请求方法, 并调用它
      
              return view
      
          def dispatch(self, request, *args, **kwargs):
              # Try to dispatch to the right method; if a method doesn't exist,
              if request.method.lower() in self.http_method_names:  # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
                  handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出该方法
              else:
                  handler = self.http_method_not_allowed
              return handler(request, *args, **kwargs)  # 返回该请求方法执行的结果
      

      再简化

      def as_view(): # 校验 + 返回view方法
          # 一些校验
          ...
          def view(): # 执行视图
              # 增加 为对象request, args, kwargs 属性
              ...
              return dispatch() # 调用指定的请求方法
          return view
      
      def dispatch(): # 真正的查找指定的方法, 并调用该方法
          ...
          return handler()
      

      调用顺序: as_view --> view --> dispatch

      • 可以看出as_view实际上是一个闭包, 它的作用做一些校验工作, 再返回view方法.
      • view方法的作用是给请求对象补充三个参数, 并调用 dispatch方法处理
      • dispatch方法查找到指定的请求方法, 并执行

      可以得出结论: 实际上真正实现查找的方法是 dispatch方法

      高内聚低耦合、生命周期 as_view() => dispatch() => 视图类响应方法

    • 相关阅读:
      简易模拟点击自动化测试工具介绍
      HttpRunner 使用简介
      postman生成测试报告
      Java 多态
      Java 接口与接口的多继承关系
      Java 类实现接口
      Java 接口内容小结
      Java 接口
      Java 抽象
      Java 继承
    • 原文地址:https://www.cnblogs.com/kai-/p/12323987.html
    Copyright © 2011-2022 走看看