Flask -- CBV

Posted q240756200

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask -- CBV相关的知识,希望对你有一定的参考价值。

CBV -- class base view(基于类视图)

在之前使用的函数叫视图叫做 FBV -- function base view (基于函数视图)

CBV 和 FBV 的区别 :

  FBV简单, 小巧, 当不涉及到复杂的逻辑时可以使用FBV

  CBV 灵活, 为什么说灵活呢, 因为, 类的封装, 继承, 多态, 你说灵活不灵活

首先,定义一个类

from flask import views    # CBV需要继承view
class Hello(views.MethodView):    # 继承view.MethodView
    methods = [get,post]
    def get(self):
        return HELLO
    def post(self):
        return WORLD

现在你会发现。类有了。路由该怎么办(也就是那个@app.route的装饰器)

app.add_url_rule(/hello,view_func=Hello.as_view(name=hello))

参数:
‘/hello‘:访问路径
view_func=类.as_view(name=‘别名‘)
在参数中有个隐藏参数endpoint,不写默认是函数名。
name是必须写的,也是一个别名,如果endpoint没有写,别名是name对应的值

看一个完整的 CBV

from flask import Flask
form flask import view app
= Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/statics" ) app.secret_key = 123 class Hello(views.MethodView): methods = [get,post] def get(self): return HELLO def post(self): return WORLD app.add_url_rule(/hello,view_func=Hello.as_view(name=hello))

基本写法有了。那么看一些这个 CBV 在源码中是什么情况

在 FBV 时。你会发现一个 @app.route()

那么 FBV 也从 route 入手 -- ctrl + 点击 route

进入源码看到这么一段代码

def route(self, rule, **options):
def decorator(f):
endpoint = options.pop("endpoint", None) # 从options中删除endpoint,没有的话就是None
self.add_url_rule(rule, endpoint, f, **options) # 调用了 add_url_rule
return f
return decorator

进入 add_url_rule

技术图片
@setupmethod
def add_url_rule(
    self,
    rule,  # 路径
    endpoint=None,  # 从 options 中取出 endpoint
    view_func=None,  # 视图函数
    provide_automatic_options=None,
    **options
):
    if endpoint is None:  # endpoint如果为None
        endpoint = _endpoint_from_view_func(view_func)  # 将试图视图函数传了进去, 返回视图函数的__name__
    options[endpoint] = endpoint  # 重新赋值endpoint, 这时endpoint有可能等于视图函数的__name__, 或还是之前的值
    methods = options.pop(methods, None)  # 将请求方式弹出

    if methods is None:
        methods = getattr(view_func, methods, None) or (GET,)
    if isinstance(methods, string_types):
        raise TypeError(Allowed methods have to be iterables of strings, 
                        for example: @app.route(..., methods=["POST"]))
    methods = set(item.upper() for item in methods)
    required_methods = set(getattr(view_func, required_methods, ()))

    if provide_automatic_options is None:
        provide_automatic_options = getattr(view_func,
                                            provide_automatic_options, None)

    if provide_automatic_options is None:
        if OPTIONS not in methods:
            provide_automatic_options = True
            required_methods.add(OPTIONS)
        else:
            provide_automatic_options = False

    methods |= required_methods

    rule = self.url_rule_class(rule, methods=methods, **options)
    rule.provide_automatic_options = provide_automatic_options

    self.url_map.add(rule)
    if view_func is not None:
        old_func = self.view_functions.get(endpoint)
        if old_func is not None and old_func != view_func:
            raise AssertionError(View function mapping is overwriting an 
                                 existing endpoint function: %s % endpoint)
        self.view_functions[endpoint] = view_func  # 重要的一句, 看样是是字典增加键值对的操作, key: endpoint: value: func
View Code

查看一下 as_view 

 @classmethod
    def as_view(cls, name, *class_args, **class_kwargs):

        def view(*args, **kwargs):
            self = view.view_class(*class_args, **class_kwargs)  # 实例化CBV对象
            return self.dispatch_request(*args, **kwargs)

        if cls.decorators:
            view.__name__ = name
            view.__module__ = cls.__module__
            for decorator in cls.decorators:
                view = decorator(view)

        # 将参数都封装到FBV 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  # 将内部函数view返回

基本流程就是这样了。。如果搞不清的话,

记住 

app.add_url_rule(路径,view_func=类.as_view(name=别名))

 

以上是关于Flask -- CBV的主要内容,如果未能解决你的问题,请参考以下文章

Flask框架—— Flask简介

Flask

Flask框架web开发

Flask(Flask_脚本项目重构)

Flask - Flask高级技巧(Advanced Flask Patterns)

Flask 学习-42.Flask-RESTX 快速入门