ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Flask快速入门(4) — CBV写法与解析

2019-09-28 19:52:57  阅读:684  来源: 互联网

标签:__ name Flask request dispatch CBV cls 写法 view


目录

方式一:继承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()

同django一样,flask中cbv模式时也是需要

1:自定义一个视图函数类,继承flask.view.View

2:执行as_view()方法,只不过在这里as_view必须要有一个参数name。这里为什么要有name呢?

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)自定义视图类继承flask.views.View时,必须要重写dispatch_request()方法。在该方法中来分发请求方式执行相应的功能

(2)在as_view()中必须要传一个name参数。就是相当于endpoint起了一个别名用于反向解析路由。有endpoint反向解析用endpoint,没有就用name的值

(3)不同的路由不能起相同的别名。应遵循路由与视图函数一一对应的元则,比如这样是不行的

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

从方法一的分析可知,在继承View的自定义视图类中必须要定义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()方法。其实还是调用的是View里的as_view,上面已经介绍过了,请求来了就执行dispatch_request方法

(2)在自定义类中没有dispatch_request方法,所以执行MethodView中的dispatch_request方法

(3)dispatch_request中判断了请求方式是否允许,以及执行请求

第二种方式已经帮我们封装好了请求分发的功能,所以是比较推荐的使用方式

标签:__,name,Flask,request,dispatch,CBV,cls,写法,view
来源: https://www.cnblogs.com/863652104kai/p/11604557.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有