Django之CBV执行流程

CBV执行流程

1. 通过中间件,进入路由

2. 根据路由匹配,一旦成功,会执行后面的函数(request)       

urls中:   
    url(r'^publish/', views.Publish.as_view(), name='publish'), 

views中: 
class Publish(View):
    def get(self, request):
        pass
    def post(self, request):
        pass

3. 本质就是执行了as_view内部的view函数

 @classonlymethod
    def as_view(cls, **initkwargs):
        """
        Main entry point for a request-response process.
        """
        for key in initkwargs:
       # 判断所传的参数是否包含 http_method_names中的元素      
       # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
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))    # 在函数内调用dispatch方法, 通过该方法判断使用了哪种方法(http_method_names中的) def view(request, *args, **kwargs): self = cls(**initkwargs) # 创建一个 cls 的实例化的对象 if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get # 为对象添加属性 self.request = request # 为对象添加属性 self.args = args # 为对象添加属性 self.kwargs = kwargs # 为对象添加属性 return self.dispatch(request, *args, **kwargs)
     # 将cls与initkwargs保存为View类中的属性, 方便以后调用 view.view_class
= cls view.view_initkwargs = initkwargs        # 将cls中所有的属性添加进view中
    # take name and docstring
from class update_wrapper(view, cls, updated=()) # 将将cls.dispatch中的所有属性添加进view中
# and possible attributes
set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=())
    # 返回view的函数地址
return view

4. 内部又调用了self.dispatch

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        
# 将request中的method小写, 并判断是否在http_method_names中, 如果不在的话就调用http_method_not_allowed方法, 直接返回405错误
  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 return handler(request, *args, **kwargs)

5. 根据请求方式,执行不同的方法(get请求,就会执行视图类中的get方法)

 

posted @ 2019-07-02 19:17  yyfgrd  阅读(314)  评论(0)    收藏  举报