• CBV请求流程源码分析


    一、CBV流程解析     

    urls.py

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^book/', views.BookView.as_view()),
    ]

    views.py

    from django.views import View
    
    class BookView(View):
        def get(self,request):
            return HttpResponse("get.........")
        def post(self,request):
            return HttpResponse("post........")

    请求走到url中,怎么执行的?

    1、先找BookView中as_view方法,没有找到,找父类View,找到View中的as_view执行,返回view

    2、执行View中的view,返回结果self.dispatch,self为自定义的类的对象,自定义类中无dispatch方法就执行View中的dispatch

    3、执行View中的dispatch,利用反射执行对应的请求函数

    二、 classbasedview的源码剖析

    base.py
    class View:
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        @classonlymethod
        def as_view(cls, **initkwargs):
           # 实例化一个对象,对象名称为self,self是cls的对象,谁调用了cls
           # cls就是谁(当前调用cls的是BookView),
            # 所以,此时的self就是BookView的实例化对象    
            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):
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
              # 此时的request对象指向原始的request对象
               # 给self这个实例化对象赋值:原始的request
                self.request = request
                self.args = args
                self.kwargs = kwargs
               # 开始执行self.dispatch()
                return self.dispatch(request, *args, **kwargs)
            view.view_class = cls
            view.view_initkwargs = initkwargs
            update_wrapper(view, cls, updated=())
    
            update_wrapper(view, cls.dispatch, assigned=())
            return view
    
        def dispatch(self, request, *args, **kwargs):
            if request.method.lower() in self.http_method_names:
               # 通过getattr找到的属性,已经和对象绑定了,访问的时候不需要在指明对象了
               # 不需要再:self.handler
               # 直接handler()
                handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)



          

  • 相关阅读:
    一张图片入门Python
    4.1. 如何在Windows环境下开发Python
    你必须知道的EF知识和经验
    XUnit的使用
    如何使用NUnit
    Entity Framework 不支持DefaultValue
    Have You Ever Wondered About the Difference Between NOT NULL and DEFAULT?
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Entity Framework 与多线程
    sqlite中的自增主键
  • 原文地址:https://www.cnblogs.com/zwq-/p/10078917.html
Copyright © 2020-2023  润新知