首页 > 其他分享 >【4.0】Flask框架之CBV

【4.0】Flask框架之CBV

时间:2023-08-26 21:44:31浏览次数:41  
标签:__ 4.0 Flask self request CBV kwargs home view

【一】基本使用

from flask import Flask, render_template

# template_folder 默认就是当前文件夹下的 templates 可以不写
app = Flask(__name__, template_folder='templates')

# FBV : 基于函数的视图
@app.route('/index', methods=['GET'])
def index():
    return 'ok'

# CBV : 基于类的视图
# CBV : 需要继承基类 MethodView , MethodView 继承了 View
from flask.views import View, MethodView

# CBV 视图函数
class Home(MethodView):
    def get(self):
        return render_template('home.html')

    def post(self):
        return "POST"

# 注册路由
app.add_url_rule('/home', endpoint='home', view_func=Home.as_view('home'))

if __name__ == '__main__':
    app.run()

【二】CBV 函数加装饰器

# -*-coding: Utf-8 -*-
# @File : 01CBV .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/8/24
from flask import Flask, render_template

# template_folder 默认就是当前文件夹下的 templates 可以不写
app = Flask(__name__, template_folder='templates')


# 登录装饰器
def auth(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        return res

    return inner


# FBV : 基于函数的视图
@app.route('/index', methods=['GET'], endpoint='index')
@auth
def index():
    return 'ok'


# CBV : 基于类的视图
# CBV : 需要继承基类 MethodView , MethodView 继承了 View
from flask.views import View, MethodView


# CBV 视图函数
class Home(MethodView):
    # MethodView 有一个类属性 decorators 可以存放装饰器
    # 如果有多个可以直接 逗号隔开
    decorators = [auth]
    # 可以控制整个视图函数的请求方式
    methods = ['GET']

    def get(self):
        return render_template('home.html')

    def post(self):
        return "POST"


# 注册路由
# as_view('home') 中的 home 其实就是 endpoint
app.add_url_rule('/home', endpoint='home', view_func=Home.as_view('home'))

if __name__ == '__main__':
    app.run()
  • 为什么decorators = [auth] 能加装饰器

  • app.add_url_rule('/home', view_func=view内存地址)

  • 用装饰器一直在装饰 view内存地址 ,所以,以后执行,就是有装饰器的view,装饰器代码会走

@auth
def view(**kwargs):
    return self.dispatch_request(**kwargs)
  • 等价于 view = auth(view)
  • view_func=Home.as_view('home') home 是 endpoint,就是路由别名
    • app.add_url_rule('/home', view_func=Home.as_view('home'))
    • add_url_rule---》endpoint没传---》会执行endpoint = _endpoint_from_view_func(view_func)
    • 取函数名作为 endpoint 的值
    • view_func是 加了一堆装饰器的view函数---》它的名字应该是装饰器的名字--》但是
      • view.__name__ = name # name 就是home
    • 所以endpoint就是你传的home
    • 如果传了endpoint,就是传的那个,那as_view('home')就没作用了,但是也必须要传

【三】CBV 源码分析

  • 入口 as.view()
def as_view(
        cls, name: str, *class_args: t.Any, **class_kwargs: t.Any
) -> ft.RouteCallable:
    if cls.init_every_request:

        def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
            self = view.view_class(  # type: ignore[attr-defined]
                *class_args, **class_kwargs
            )
            # 支持异步操作
            return current_app.ensure_sync(self.dispatch_request)(**kwargs)

    else:
        self = cls(*class_args, **class_kwargs)

        def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
            return current_app.ensure_sync(self.dispatch_request)(**kwargs)
	
    # 装饰器列表
    if cls.decorators:
        view.__name__ = name
        view.__module__ = cls.__module__
        # 遍历每一个装饰器
        for decorator in cls.decorators:
            # 装饰器语法糖干的事: 
            #把被装饰的函数当参数传入到装饰器,返回结果赋值给被装饰的函数,一个个用装饰器包装view
            view = decorator(view)

    view.view_class = cls  # type: ignore
    view.__name__ = name
    view.__doc__ = cls.__doc__
    view.__module__ = cls.__module__
    view.methods = cls.methods  # type: ignore
    view.provide_automatic_options = cls.provide_automatic_options  # type: ignore
    # 返回 view 函数
    return view
  • view
if cls.init_every_request:

    def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
        self = view.view_class(  # type: ignore[attr-defined]
            *class_args, **class_kwargs
        )
        # 支持异步操作
        return current_app.ensure_sync(self.dispatch_request)(**kwargs)

else:
    self = cls(*class_args, **class_kwargs)


    def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
        return current_app.ensure_sync(self.dispatch_request)(**kwargs)
  • 调用了 dispatch_request 方法
    • 我们发现这是一个抛异常的函数
def dispatch_request(self) -> ft.ResponseReturnValue:
    """The actual view function behavior. Subclasses must override
    this and return a valid response. Any variables from the URL
    rule are passed as keyword arguments.
    """
    raise NotImplementedError()
  • 其实我们应该去找 父类 的 dispatch_request 方法
    • MethodViewdispatch_request 方法
def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue:
    # request.method.lower() 获取到 method 的小写 假设是get请求
    # meth 就是 CBV 中以get命名的方法
    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, f"Unimplemented method {request.method!r}"
    # 执行方法
    return current_app.ensure_sync(meth)(**kwargs)

标签:__,4.0,Flask,self,request,CBV,kwargs,home,view
From: https://www.cnblogs.com/dream-ze/p/17659501.html

相关文章

  • Ubuntu系统编译opencv4.0以上以及opencv_contrib
    一、安装依赖   sudoaptinstallbuild-essentialcmakelibtbb2libttb-devlibgtk-3-dev   sudoaptinstallpython3python3-devpkg-config   sudoaptinstalllibjpeg-devlibpng-devlibtiff-devlibjasper-dev   sudoaptinstallzlib1gzlibe1g-dev......
  • AppSpider Pro 7.4.054 for Windows - Web 应用程序安全测试
    AppSpiderPro7.4.054forWindows-Web应用程序安全测试Rapid7DynamicApplicationSecurityTesting(DAST)请访问原文链接:https://sysin.org/blog/appspider/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgappspider没有任何应用程序未经测试,没有未知风险......
  • 首秀就冲上PCIe 4.0 SSD巅峰!Solidigm P44 Pro 1TB评测:缓外也有1.4GB
    一、前言:英特尔+SK海力士强强联合Solidigm推出旗舰产品P44ProSolidigm作为新兴品牌,原本是英特尔的NAND闪存存储业务,由SK海力士收购之后独立组建运营的子公司。英特尔的SSD可以说是大名鼎鼎,无论是消费级,还是企业级,在性能、稳定性、功耗上都非常出色,在市面上皆有口碑。现在,现在......
  • Python Web:Django、Flask和FastAPI框架对比
    Django、Flask和FastAPI是PythonWeb框架中的三个主要代表。这些框架都有着各自的优点和缺点,适合不同类型和规模的应用程序。Django:Django是一个全功能的Web框架,它提供了很多内置的应用程序和工具,使得开发Web应用程序更加容易。Django采用了MTV(模型-模板-视图)设计模式,提供ORM......
  • Python-Flask配置https证书
    零、问题错误:SSLVersion2and3ProtocolDetection一、说明1、通过使用flask框架配置https证书进行HTTPs证书配置后会被扫描到漏洞,漏洞描述如下:远程服务接受使用SSL2.0和/或SSL3.0加密的连接。这些版本的SSL受到多个加密缺陷的影响,包括:-带CBCCiphers的不安全的填充方案。......
  • python-flask小结
    1.flask和django区别1.flask是一个轻量级的,django是一个重量级的,包含了很多组件,包括admin,orm等,flask虽然没有但可以引入第三方组件。2.flask是基于上下文管理做的一个应用上下文appcontext和请求上下文requestcontext管理。django只是通过参数传递。2.flask生命周期......
  • flask接收json,开启服务demo
    demofromflaskimportFlask,render_template,request,jsonifyapp=Flask(__name__)@app.route('/',methods=['GET','POST'])defindex():processed_data=Noneifrequest.method=='POST':try......
  • flask路由、模板、请求响应、session
    目录一路由系统1.1flask路由系统的参数1.2转换器(了解)1.3路由系统本质-->读源码1.4endpoint1.5flask写接口api二CBV2.2as_view源码三模板四请求响应五session一路由系统#1flask路由系统是基于装饰器的:参数如下#2转换器:#3路由系统本质#4endpoint不传会......
  • flask介绍
    目录一web框架介绍1.2fastapi二flask2.1第一个flask项目2.2pycharm创建flask框架(可以不用)三wsgiref四Werkzeug五Flask快速使用5.1登录显示用户信息的小案例login.htmlindex.htmldetail.html总结5.2登录认证加装饰器语法糖六配置文件6.1方式一6.2方式二:app.config6.3......
  • flask项目结构参考
    project_name/├──app/│├──models/│├──views/│├──controllers/│├──templates/│├──static/│├──forms/│├──utils/│├──init.py│└──config.py├──instance/│└──config.py├──......