flask中的CBV和FBV
flask中CBV使用
-
from flask import Flask, views
-
-
app = Flask(__name__)
-
-
-
class Login(views.MethodView):
-
methods = ['POST', 'GET']
-
# 如果需要在CBV中加装饰器的话,括号里就是装饰器的内存地址,可以传多个
-
decorators = ()
-
-
def get(self):
-
print('get 请求')
-
return 'login get'
-
-
def post(self):
-
print('post 请求')
-
return 'login post'
-
-
-
app.add_url_rule('/login', view_func=Login.as_view(name='login'))
-
-
if __name__ == "__main__":
-
app.run(debug=True)
Login.as_view(name='login')
先对这段代码就行解析吧
Login
: 它是我们写一个视图类对吧
as_view
: 由类直接调用,他应该就是类里的一个函数(这里看不错它是对象方法,还是类方法,还是静态方法),
因为类可以调用它下面的所有函数对吧,在我们的Login
并没有写as_view
这个函数,所以这个函数应该在它继承的类中,我们顺着这个基类去找找看,最终我们在View这个类中找到
它做了下面这几件事:
- 最开始定义了一个
view
函数 - 再判断
cls.decorators
,这里的cls
就是我们所定义的视图类Login
,假如我们视图类没有写decorators
这个属性,那么最终会在View
这个类中找到该属性,默认为一个空元组,所以说布尔值默认False,如果我们在自定义的试图类中假如的装饰器,也就是说decorators
它是有值的,一个元组或列表,最终会for循环decorators
的值,并一层一层的包裹,所以你写的装饰器顺序是需要注意下的 - 然后就是给
view
函数赋值操作了,python中一切皆对象,所以这个函数也是一个对象 - 最后返回了定义的
view
函数的内存地址 - 那么我们在创建路由和视图关系那里,也就是这条
app.add_url_rule('/login', view_func=Login.as_view(name='login'))
,其中的view_func
应该是view
的内存地址了 - 最后就会执行
app.add_url_rule
这个函数,这个函数才会创建号路由视图之间的关系
提醒一点:
-
在上面的
app.add_url_rule
这个方法里,我并没有写endpoint
这个属性,那么最终会以view_func
所对应的函数的__name__
方法作为endpoint
的值,那么我上面代码的基础上再写一个Register
的视图函,再创建一个路由试图关系,也就是执行app.add_url_rule
,他们的view_func
对应的都是view
函数的内存地址,你说会不会报错呢?答案:是不会报错的,因为你在
as_view
方法里传了一个name
的参数,其实这个name
相当于就是endpoint
,所以这个name
你是不可以相同的,在as_view
方法里,它有这样的一步操作view.__name__=name
,所以返回的view
的__name__
的值是不同的。
那么来了一个请求,它的url是/login
,然后这个视图类中是怎么执行的呢?
-
首先我们创建路由关系,比如这样的 "/login" -->> (这是允许请求的方法) -->> login(记住这是
endpoint
的值,其实他真正对应的是view
这个函数的内存地址) -
请求来了,便会去执行这个
view
函数view.view_class
:就是Login
视图类,那么self
就是Login
的实例对象最终返回了
self.dispatch_request(*args, **kwargs)
这个方法的返回值 -
很明显我们写的
Login
视图类中没有dispatch_request
这个方法,那么我们继续在它的基类里寻找,最终在MethodView
这个基类里找到了-
request.method.lower()
就是这次请求的方法,self
就是Login
的实例对象,通过getattr获取到以请求方法小写的方法的内存地址。这里根本没有判断该视图类允许的请求方法,所以说我在写视图类的时候,
methods
这个属性是不是可以不用写呢?等下我去试试 -
然后就是一系列的判断,断言什么的,很容易看懂就不说了
-
最终是执行了
meth
这个方法,将它的返回值返回回去 -
所以说
view
这个函数的返回值,也就是meth
的返回值
-
总结下CBV:
-
写一个定义CBV流程:
-
首先导入views,`from flask import views
-
自定义一个视图类,并且继承
Views.MethodView
-
如果你要给你的视图类加装饰器的话,在该视图类中写
decorator
,它是一个列表,你把装饰器函数的内存地址写进去好了 -
然后根据不同的请求,写相应的方法,比如对get请求写相关的方法,
def get(self):pass
就好了,其他请求方法都是一个 -
最后配置好路由和视图函数之间的关系就好了
app.add_url_rule('路径',view_func=视图类.as_view(name='一般就以视图类名小写吧,总之不能有重名'))
-
-
写执行CVB的流程
- 一个请求来了,通过url找到相应的
view
函数,加括号执行 - 再执行
dispatch_request
方法 - 通过本次请求的方式名小写,获取到视图类对应的方法名
- 执行该方法,最终将返回值返回。
- 一个请求来了,通过url找到相应的
flask中FBV
没啥好讲的,写段FVB的代码吧
-
from flask import Flask
-
-
app = Flask(__name__)
-
-
-
def index():
-
return "index page"
-
-
-
if __name__ == "__main__":
-
app.run(debug=True)
转载于:https://www.cnblogs.com/zhuchunyu/p/10466512.html