4.CBV和FBV
前面的例子中,都是基于视图函数构建视图(FBV),和Django一样,Flask也有基于类构建视图(CBV)的方法。这种方式用的不多,可了解。
由于视图类本身不是添加到路由系统的视图函数,真正的视图函数是类的as_view()
的返回值。并且手动使用app.add_url_rule()
函数添加路由。
视图类中主要有两个常用的属性:
- methods:表明可接受的请求方法,是个列表,可选多个;
- decorators:表明需要加在这个类的视图函数上的装饰器,是个列表,可选多个;
CBV有如下两种方式:
4.1 继承 views.View
继承 views.View。在dispatch_request
函数中写具体的处理逻辑,不同的请求方法需要判断。
# CBV示例
from flask import Flask, views
import functools
app = Flask(__name__)
def wapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print("inner")
return func(*args, **kwargs)
return inner
class IndexView(views.View):
methods = ['GET', 'PUT']
# 添加装饰器,加载这个类下的方法上
decorators = [wapper, ]
def dispatch_request(self):
if request.method == 'GET':
print('GET Index')
return 'Index'
else if request.method == 'PUT':
print('PUT Index')
return 'Index'
app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name是endpoint
if __name__ == '__main__':
app.run()
4.2 继承 views.MethodView
每个 HTTP 方法都映射到一个同名的类方法(名称为小写字母),可以完成反射。
# CBV示例
from flask import Flask, views
import functools
app = Flask(__name__)
def wapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print("inner")
return func(*args, **kwargs)
return inner
class IndexView(views.MethodView):
methods = ['GET', 'POST']
# 添加装饰器,加载这个类下的方法上
decorators = [wapper, ]
def get(self):
print('get 请求')
return 'get'
def post(self):
print('post 请求')
return 'post'
app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name是endpoint
if __name__ == '__main__':
app.run()
使用这种方式,也可不提供 methods
属性,它会自动使用相应的类方法。