一、CBV与FBV
#Class Base View(基于类的视图) #Function Base View(基于函数的视图)
二、CBV的用法及源码分析
1、用法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#视图层 # 1 先导入View(继承它) from django.views import View # 写一个类继承它, class Test(View): #request必须传,后面的可传可不传(有可能有名,无名分组) def get(self, request, *args, **kwargs): print('get') return render(request, 'login.html') def post(self, request): name = request.POST.get('name') pwd = request.POST.get('pwd') if name == 'pdun' and pwd == '123': return HttpResponse('登录成功') else: return render(request, 'login.html', {'error': '用户名或密码错误'}) #路由层 urlpatterns = [ # as_view一定要加括号,as_view()哪里来的? 从View中继承过来的 # as_view用类来调用的,它是一个类方法 # 猜:as_view这个方法执行完成以后,应该是个函数的内存地址 # 如果是get请求,会响应到类内部,执行get方法post请求,一样 # as_view 类方法,自动把自己传过来 url(r'^login/', views.Test.as_view()), #模板层与FBV相同 <body> <form action="" method="post"> <p>用户名: <input type="text" name="name"></p> <p>密码: <input type="password" name="pwd"></p> <p><input type="submit" value="提交">{{ error }}</p> </form> </body>
2、源码分析
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
class View(object): http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] @classonlymethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): #这是一个闭包函数 self = cls(**initkwargs) #判断self类中是不是有该(get)方法 if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs #如果类中没有写dispatch,会执行View中的dispatch方法 return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs return view def dispatch(self, request, *args, **kwargs): #request.method 前台请求的方法,转成了小写 #http_method_names View中定义的一个列表:在上边 if request.method.lower() in self.http_method_names: #getattr的第三个参数是默认值:self.http_method_not_allowed #拿到get方法的内存地址 handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#闭包函数,内部函数包含外部函数的名称空间 def bar(): x=8 y=8 def inner(): q=x+y print(q) inner.x=1 #注意这里,不是更改X print(inner.__dict__) return inner bar()() {'x': 1} 16
#读源码总结 #CBV:基于类的视图 #导入from django.views import View #自定义类继承View #自定义的类中只能是如下方法: #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] #请求流程:as_view() 的返回值是他内部view函数的内存地址 #dispatch方法,总的分发方法 #补充:装饰器的装饰方法 url(r'^test/', csrf_exempt(views.test)), #总结: #路由配置好,项目启动:as_view()---->返回结果是一个函数的内存地址 #请求来了---->触发函数的执行,就会执行dispatch方法---->根据请求的不同,分发到不同的视图函数