Flask Quick Start (4) - CBV writing and analysis

Method 1: Inheritance View

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()

Like django, when the flask in cbv model is needed

1: a view of a custom function classes, inheritance flask.view.View

2: Perform as_view () method, except where as_view must have a parameter name. Why here have a name yet?

3: dispatch_request method defined function in the view class, why it is necessary to write the way to do it.

Look at the source code how to perform, the way to answer doubts. The first is performed as_view view class method. First look in a custom class, then look no parent, that View.as_view ()

as_view () source code analysis

@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()函数 

to sum up:

(1) a custom view class inheritance flask.views.View, that must be rewritten dispatch_request () method. In this method the distribution request to the embodiment performs a corresponding function

(2) in as_view () must pass in a parameter name. Which is equivalent endpoint played an alias for reverse lookup routing. There endpoint reverse analysis by endpoint, not on the value of a name

(3) Different routes can not play the same alias. Should follow and the route element is one-view function, such as this is not acceptable

app.add_url_rule('/index', view_func=IndexView.as_view(name='name'))
app.add_url_rule('/login', view_func=IndexView.as_view(name='name'))

Second way: inheritance 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()

Seen from the analysis method, the method must be defined dispatch_request view class inheritance Custom View, the corresponding function is achieved in this method is determined by the way the request. In MethodView class has helped us achieve dispatch_request. Let's take a look at MethodView source:

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) performs as_view () method. In fact, the call is still in the View as_view, above, has been introduced, the request came on the implementation of the method dispatch_request

(2) method not dispatch_request custom class, the execute method MethodView in dispatch_request

(3) dispatch_request determined whether to allow a request method, and the execution request

The second approach has helped us a good package distribution of feature requests, it is more recommended use

Guess you like

Origin www.cnblogs.com/863652104kai/p/11604557.html