码迷,mamicode.com
首页 > 其他好文 > 详细

FBV与CBV 及CBV源码分析

时间:2019-10-23 21:45:17      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:string   csr   结束   from   路由   ready   html   方法   entry   

FBV与CBV 及CBV源码分析

FBV(Function Based View) 基于函数的视图

基于函数的视图,我们一直在用没啥好讲的,就是导入模块调用函数执行业务

CBV(Class Based View) 基于类的视图

路由

from app01 import views

url(r'^haha/',views.zx_view.as_view()),

视图

class zx_view(View):
    def get(self,request):
        return render(request,'edit.html')
    def post(self,request):
        return HttpResponse("你好我是POST")

CBV源码分析

首先我们的路由竟然是一个函数(),这样的话是直接执行的,我们找到返回值就行

url(r'^haha/',views.zx_view.as_view()),

进入源码

@classonlymethod
    def as_view(cls, **initkwargs):
        """
        Main entry point for a request-response process.
        """
        #views.zx_view.as_view(),我们调用的时候并没有传递关键字参数,所以这个for可以跳过
        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
            self.request = request
            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

路由就相当于是这个了

那么就和FBV一样了,路由触发函数的执行

url(r'^haha/',view),

触发路由查看view是怎么执行的

def view(request, *args, **kwargs):
            #这个self是什么,就是我们之前创建的zx_view类对象,这里直接实例化了一个self对象
            self = cls(**initkwargs)
            #通过反射获取get方法
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            #给self对象添加属性
            self.request = request
            self.args = args
            self.kwargs = kwargs
            #最后执行self.dispatch(request, *args, **kwargs)
            return self.dispatch(request, *args, **kwargs)

self.dispatch我们知道我们的zx_view是没有这个方法的,那么就去它的父类找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.
        #获取请求方法并转换成小写,判断是否在http_method_names,http_method_names信息下面那段代码
        if request.method.lower() in self.http_method_names:
            #通过反射拿到zx_view的get或者post函数对象
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        #执行zx_view的get或者post函数对象,并返回结果,结束
        return handler(request, *args, **kwargs)
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

FBV与CBV 及CBV源码分析

标签:string   csr   结束   from   路由   ready   html   方法   entry   

原文地址:https://www.cnblogs.com/zx125/p/11729062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!