方法1:継承ビュー
from flask import Flask, views
app = Flask(__name__)
class IndexView(views.View):
methods = ['GET']
def dispatch_request(self):
print('index')
return 'Index!'
app.add_url_rule('/index', view_func=IndexView.as_view(name='name'))
if __name__ == '__main__':
app.run()
CBVモデルでフラスコが必要とされているジャンゴ、同様に
1:カスタム関数クラス、継承の観点flask.view.View
2:as_viewは、パラメータ名を持たなければならない場合を除いて、as_view()メソッドを実行します。ここにはまだ名前を持っているのはなぜ?
3:それを行う方法を記述する必要がある理由ビュークラス、中dispatch_request方法定義関数。
、疑問に答えるための方法を実行するためにどのようにソースコードを見てください。最初はビュークラスメソッドas_view行われます。カスタムクラスの第一印象は、その後、親、そのView.as_viewを(見ていません)
as_view()ソースコード解析
@classmethod # 是一个类方法,此时cls表示自定义的类IndexView
def as_view(cls, name, *class_args, **class_kwargs): # 第一个位置参数没有默认值,所以必须要传
def view(*args, **kwargs): # 请求来了执行
self = view.view_class(*class_args, **class_kwargs) # cls()实例化一个对象
return self.dispatch_request(*args, **kwargs) # 执行dispath_request()方法,如果在自定义类中没有定义该方法,则执行父类的dispatch_request(),点进去其实就是raise NotImplementedError()
if cls.decorators:
view.__name__ = name
view.__module__ = cls.__module__
for decorator in cls.decorators:
"""在这里对decorators循环遍历,然后再将view函数传入执行。其实就是装饰器"""
view = decorator(view)
view.view_class = cls
view.__name__ = name # 给view函数重命名,这样在该方法 return view时返回的是不同的函数名,遵循路由与视图函数一一对应的元则
view.__doc__ = cls.__doc__
view.__module__ = cls.__module__
view.methods = cls.methods
view.provide_automatic_options = cls.provide_automatic_options
return view # 返回的是一个函数名,这样当请求来的时候执行的就是view()函数
要約:
(1)dispatch_request()メソッドを書き換えなければならないカスタム・ビュー・クラスの継承flask.views.View、。この方法では実施の形態に配信要求は、対応する機能を実行します
(2)as_viewに()パラメータ名を渡す必要があります。これは、逆引きルーティングのためのエイリアスを果たした同等のエンドポイントです。ない名前の値に、エンドポイントで逆解析がエンドポイント
(3)さまざまなルートが同じエイリアスを再生することはできません。これは許容されないような、追従及びルート要素は、1つビュー関数であるべきです
app.add_url_rule('/index', view_func=IndexView.as_view(name='name'))
app.add_url_rule('/login', view_func=IndexView.as_view(name='name'))
第二の方法:継承MethodView
from flask import Flask,views
app = Flask(__name__)
class IndexView(views.MethodView):
methods = ['GET','POST']
def get(self):
return 'index get method'
def post(self):
return 'index post method'
app.add_url_rule('/index',view_func=IndexView.as_view(name='hello'))
if __name__ == '__main__':
app.run()
分析方法から見た、方法が定義されなければならないdispatch_requestビュークラスの継承カスタムビューは、対応する機能が要求方法によって決定され、この方法で達成されます。MethodViewクラスで私たちはdispatch_requestを達成支援してきました。のは、MethodViewソースを見てみましょう。
class MethodView(with_metaclass(MethodViewType, View)):
def dispatch_request(self, *args, **kwargs):
# self是自定义的视图类,判断来的请求方式请否允许并获取
meth = getattr(self, request.method.lower(), None)
if meth is None and request.method == "HEAD":
meth = getattr(self, "get", None)
assert meth is not None, "Unimplemented method %r" % request.method
return meth(*args, **kwargs) # 比如请求方式为get,到这里就是执行get()
(1)as_view()メソッドを実行します。実際には、呼び出しが表示as_viewにまだある、上記、導入された、要求は、メソッドdispatch_requestの実装に来ました
(2)の方法ではないdispatch_requestカスタムクラス、dispatch_requestで実行方法MethodView
(3)リクエストメソッド、および実行要求を許可するかどうかを判断dispatch_request
第二のアプローチは、それがより推奨される使用され、私たちに機能要求の良いパッケージの配布を支援してきました