21 django之FBV与CBV
一、FBV与CBV
1.FBV 基于函数的视图
def index(request): return HttpResponse(...)
2.CBV 基于类的视图——CBV会自动判断当前请求方法并自动匹配类中的方法执行
# 视图函数即可以是函数也可以是类 from django.views import View class MyLogin(View): def get(self, request): return HttpResponse('get请求') def post(self, request): return HttpResponse('post请求')
url(r'^login/', views.MyLogin.as_view()) """CBV会自动判断当前请求方法并自动匹配类中的方法执行"""
from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), #FBV url(r"^index/",views.index), #CBV url(r"^login/",views.MyLogin.as_view()) ]
为何能够做到自动匹配并执行??
二、CBV源码剖析——反射:通过字符串来操作对象的属性或者方法
函数名或者方法名遇到括号执行优先级最高
对象查找属性或方法的顺序
永远都是先从自己身上找
然后去产生对象的类中找
再去类的父类中找 如果都没有才会报错
闭包函数
定义在函数内部并且使用了外层函数名称空间中的名字
回去记得复习面向对象反射
FBV与CBV在路由匹配上本质其实是一样的
都是正则表达式对应函数名
温故知新:getattr通过字符串的形式获取对象的属性或方法
口头表述CBV底层逻辑
1. url(r"^login/",views.MyLogin.as_view()) as_view())里定义了一个view函数 2.view里面调用了一个self.dispatch 3.利用反射获取当前的方法,去类里面找有没有跟方法相同的方法名 4.找到了执行
# 突破口在urls.py
url(r'^login/',views.MyLogin.as_view())
# url(r'^login/',views.view) FBV一模一样
# CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
"""
函数名/方法名 加括号执行优先级最高
猜测
as_view()
要么是被@staicmethod修饰的静态方法
要么是被@classmethod修饰的类方法 正确
@classonlymethod
def as_view(cls, **initkwargs):
pass
"""
@classonlymethod
def as_view(cls, **initkwargs):
"""
cls就是我们自己写的类 MyCBV
Main entry point for a request-response process.
"""
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls是我们自己写的类
# self = MyLogin(**initkwargs) 产生一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
"""
以后你们会经常需要看源码 但是在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序
先从对象自己找
再去产生对象的类里面找
之后再去父类找
...
总结:看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁
"""
return view
# CBV的精髓
def dispatch(self, request, *args, **kwargs):
# 获取当前请求的小写格式 然后比对当前请求方式是否合法
# get请求为例
# post请求
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
"""
反射:通过字符串来操作对象的属性或者方法
handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
handler = 我们自己写的类里面的get方法
"""
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
"""
自动调用get方法
"""
FBV与CBV在路由匹配上本质其实是一样的 都是正则表达式对应函数名 url(r'^login/', views.MyLogin.as_view()) def as_view(cls, **initkwargs): def view(request, *args, **kwargs): # cls使我们自定义的类 MyLogin self = cls(**initkwargs) # 产生一个MyLogin类的对象 obj return self.dispatch(request, *args, **kwargs) return view def dispatch(self, request, *args, **kwargs): 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)