view 源码
@classmethod
def as_view(cls, name, *class_args, **class_kwargs): # cls = 视图类 name一定要传值
def view(*args, **kwargs):
# view_class = cls 视图类
self = view.view_class(*class_args, **class_kwargs) # 实例化视图类,self 是视图类对象
# self调用dispatch_request方法,调用的是视图类中的dispatch_request方法,完成方法映射
return self.dispatch_request(*args, **kwargs) # 视图类必须实现dispatch_request此方法
if cls.decorators:
view.__name__ = name
view.__module__ = cls.__module__
for decorator in cls.decorators:
view = decorator(view)
# 在 view的名称空间中添加下面的键值对
view.view_class = cls # cls是视图类
view.__name__ = name # name是路由别名
view.__doc__ = cls.__doc__
view.__module__ = cls.__module__
view.methods = cls.methods # 视图类中的methods
view.provide_automatic_options = cls.provide_automatic_options
return view
as_view -> view(View中的) -> dispatch_request(视图类中的)
- 普通使用
from flask import Flask, views
app = Flask(__name__)
class IndexView(views.View):
methods = ['POST', 'GET']
# decorators = [ ]
def dispatch_request(self): # 继承views的视图类必须实现dispatch_request方法
print('Index')
return 'Index'
app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))
'''
methods = [] 视图类的请求方式, 默认GET, 若指定了请求方式,就只能用指定的方式请求该视图类
as_view(name='index') 要指定name = 别名, 若不指定,导致所有的路由都是view,别名一样报错
'''
MethodView 源码
MethodView 继承views类, 主要就是实现了dispatch_request方法,完成分发
class MethodView(with_metaclass(MethodViewType, View)):
# 重写dispatch_request方法
def dispatch_request(self, *args, **kwargs): # self是视图类的对象
# 从self中获取request中的请求方式,并改成小写
meth = getattr(self, request.method.lower(), None) # 核心 使前端请求方式与视图类中的请求方式对应
# If the request method is HEAD and we don't have a handler for it
# retry with GET.
# 如果 meth是空并且请求方式是HEAD
if meth is None and request.method == "HEAD":
# 从self中获取get方法
meth = getattr(self, "get", None)
# meth为空抛出错误
assert meth is not None, "Unimplemented method %r" % request.method
# 当前端的请求方式在视图类中有时,
# meth不为空,并调用meth映射的请求方式,返回
# 否则meth为空抛出异常
return meth(*args, **kwargs)
as_view -> view(View中的) -> dispatch_request(MethodView中的)
- 指定post / get
from flask import Flask, views
app = Flask(__name__)
class LoginView(views.MethodView):
# methods = ['GET'] # 默认支持 GET/POST ,若指定请求方式,该视图类只能用指定的方式
def get(self):
print('get')
return 'get'
def post(self):
print('post')
return 'post'
app.add_url_rule('/login', view_func=LoginView.as_view(name='login'))