flask特性之methodview
大型项目中,代码不仅仅是功能的实现,更主要在于代码的可维护性、可读性以及良好的代码组织结构。为了实现这些特性,methodview和blueprint就是flask的两大利器。blueprint在之前的文章为们已经分析完毕,接下来看看methodview的魅力。
methodview使用示例:
from flask.views import MethodView
class CounterAPI(MethodView):
    def get(self):
        return session.get('counter', 0)
    def post(self):
        session['counter'] = session.get('counter', 0) + 1
        return 'OK'
app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter'))methodview在使用时,路由的逻辑和app.route是一致的,关键在于MethodView类的as_view方法,那它是如何实现的呢?
MethodView的实现:
class View(object):
    methods = None
    provide_automatic_options = None
    decorators = ()
    def dispatch_request(self):
        """Subclasses have to override this method to implement the
        actual view function code.  This method is called with all
        the arguments from the URL rule.
        """
        raise NotImplementedError()
    @classmethod
    def as_view(cls, name, *class_args, **class_kwargs):
        def view(*args, **kwargs):
            self = view.view_class(*class_args, **class_kwargs)
            return self.dispatch_request(*args, **kwargs)
        if cls.decorators:
            view.__name__ = name
            view.__module__ = cls.__module__
            for decorator in cls.decorators:
                view = decorator(view)
        # 对view函数的属性修改
        view.view_class = cls
        view.__name__ = name
        view.__doc__ = cls.__doc__
        view.__module__ = cls.__module__
        view.methods = cls.methods
        view.provide_automatic_options = cls.provide_automatic_options
        return view
class MethodView(with_metaclass(MethodViewType, View)):
    def dispatch_request(self, *args, **kwargs):
        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.
        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)可以看到MethodView类的as_view是集成自父类View,可以看到as_view被装饰成classmethod,as_view内部定义view函数,并将其返回来充当url对应的view_func,我们详细看一下view函数本身处理的逻辑,也就是当请求到达时,view函数的处理过程。简单来看就是self是view.view_class的实例化对象,而后把请求相关参数传递给self.dispatch_request,处理请求,最后返回。在View类中as_view函数中,我们可以看到在内部函数view返回时,对view函数的本身的属性进行了修改,包括view_class、__doc__、__module__、methods.provide_automatic_options。这都是在添加路由映射时app.add_url_rule所需的关键信息。
在View类中,我们可以看到一个decorators属性,从名称上看,这是装饰器列表,我们可以提供自己的装饰器,在修改view函数的运行时行为,做到程序高内聚,低耦合。
Last updated
Was this helpful?
