首页 > 其他分享 >flask-

flask-

时间:2023-04-03 17:45:47浏览次数:43  
标签:endpoint name flask self request func view

1.flask写cbv

1.1 cbv模板

之前我们都是写fbv,现在我们写cbv,这样可以把get请求写在一个视图类中:

from flask import Flask, request
from flask.views import View, MethodView

app = Flask(__name__)

'''每次修改之后项目会自己启动'''
app.debug = True


class IndexView(MethodView):
    '''在这里不用再把request加入形参,直接使用全局的request就可以'''

    def get(self):
        print(request.method)
        return 'get请求'

    def post(self):
        print(request.method)
        return 'post 请求'

'''endpoint是别名,as_view()括号内也要写别名,后面详解'''
app.add_url_rule('/index',endpoint='index',view_func=IndexView.as_view('index'))
if __name__ == '__main__':
    app.run()

image
image

1.2 cbv源码分析

1.首先我们需要从as_view()源码中分析,点进原码:

    def as_view(
        cls, name: str, *class_args: t.Any, **class_kwargs: t.Any
    ) -> ft.RouteCallable:
            def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
                self = view.view_class(  # type: ignore[attr-defined]
                    *class_args, **class_kwargs
                )
# 不管走if分支还是else分支,都会返回一个current_app.ensure_sync(self.dispatch_request)(**kwargs)。这句代码其实是在执行self.dispatch_request,只不过是异步执行
                return current_app.ensure_sync(self.dispatch_request)(**kwargs)
        return view

2.当请求来了之后,执行view(),本质还是在执行self.dispatch_request,所以我们现在需要找到dispatch_request源码(我们直接点进去发现什么都没有,这是因为我们直接点进去的是View下的dispatch_request源码,而我们的self是视图类的对象,查找顺序是:对象名称空间(没有)>>>视图类名称空间(没有)>>>MethodView名称空间(找到了)):

   def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue:
        meth = getattr(self, request.method.lower(), None)
		'''meth通过反射拿到了视图类中的post或者get,此时的meth就是get或者post'''
        if meth is None and request.method == "HEAD":
            meth = getattr(self, "get", None)
		'''异步执行了get()或者post()'''
        return current_app.ensure_sync(meth)(**kwargs)

1.3 as_view()参数分析

当我们在as_view()中不传参数时,项目无法启动。所以as_view()中必须要传参数。这是因为as_view()的返回值是view,所以如果我们不传参数,所有的返回值都是view,结果一样那么必然会报错。
view源代码:

		'''view中的形参**kwargs使用了其外层函数as_view中的参数,所以这是一个闭包函数'''
            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)
			...
		view.view_class = cls  # type: ignore
		view.__name__ = name

view中的形参使用了as_view()中的参数,所以这是一个闭包函数。view.name = name,view就是闭包函数内的view,这句代码是修改了函数的名字。

拓展:当我们print(函数名.name)拿到的是一个函数名,当然我们也可以自己修改其名称,再次打印其名字就是修改之后的:

def index():
    pass

print(index.__name__)  # index
index.__name__ = 'add'
print(index.__name__)  # add

紧接上面,其实我们可以简写生成路由代码:

app.add_url_rule('/index',view_func=IndexView.as_view('index'))
# 等同于:
app.add_url_rule('/index',view_func=view)

所以如果我们不传endpoint参数,并且不在as_view()中传参数的话,那么所有的view都是一个,就会报错。
image
下面我们来看endpoint和as_view()中参数的关系,首先查看add_url_rule源码:

    @setupmethod
    def add_url_rule(
        self,
        rule: str,
        endpoint: t.Optional[str] = None,
        view_func: t.Optional[ft.RouteCallable] = None,
        provide_automatic_options: t.Optional[bool] = None,
        **options: t.Any,
    ) -> None:
        if endpoint is None:
            endpoint = _endpoint_from_view_func(view_func)  # type: ignore

查看_endpoint_from_view_func源码:如果endpoint没有传入,执行以下代码,直接返回view_func对应函数的名字

def _endpoint_from_view_func(view_func: t.Callable) -> str:

    assert view_func is not None, "expected view func if endpoint is not provided."
    return view_func.__name__

标签:endpoint,name,flask,self,request,func,view
From: https://www.cnblogs.com/ERROR404Notfound/p/17283790.html

相关文章

  • Flask 和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、
    Flask和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、路由系统Flask和pythonweb框架介绍Flask和pythonweb框架的区别:Django框架: 大而全,内置的app很多,第三方的app很多Flask框架: 小而精,没有过多的内置app,只能完成web框架的基本功能,很多功能......
  • Flask框架cbv的写法、请求与响应、请求扩展、session源码分析、闪现
    本篇文章将会详细讲在flask框架如何写cbv、请求与响应、请求扩展、session源码分析、闪现等知识点。目录一、flask写CBV二、请求与响应三、session四、闪现flash五、请求扩展一、flask写CBVCBV源码分析的结论如下1as_view执行流程跟djagno一样2路径如果不传别名,别名就是......
  • 1 Flask 和pythonweb框架介绍、2 flask快速使用 、3 登录,显示用户信息小案例、4 配置
    目录1Flask和pythonweb框架介绍1.1flask介绍2flask快速使用3登录,显示用户信息小案例3.1login.html3.2home.html3.3detail.html3.4py文件4配置文件方式5路由系统5.1路由本质5.2路由参数add_url_rule5.3转换器1Flask和pythonweb框架介绍#pythonweb框架,本质都一......
  • Flask 和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、
    目录1Flask和pythonweb框架介绍1.1flask介绍2flask快速使用3登录,显示用户信息小案例3.1login.html3.2home.html3.3detail.html3.4py文件4配置文件方式5路由系统5.1路由本质5.2路由参数add_url_rule5.3转换器1Flask和pythonweb框架介绍#pythonweb框架,本质都一......
  • Flask基础01
    1Flask和pythonweb框架介绍#pythonweb框架本质都一样 -django:大而全,内置的app多,第三方app也多-Flask:小而精,没有过多的内置组件,只完成web框架最基本的功能,需要借助于第三方,完成更丰富的功能-web.py:是一个小巧灵活的Python框架,它简单而且功能强大(国内几乎没有......
  • Flask入门
    Flask入门常见python-web框架:django:大而全的web框架,自己内置了很多app,第三方适配的模块也多,但由于过于全,在开启小项目时,略显臃肿。flask:小而精的python-web框架,甚至可以在一个py文件中完成web最基础的功能,而完成更丰富的功能则需要借助第三方模块。web.py:是一个小巧灵活的Py......
  • Flask的url_for怎么传参?url_for('方法名', key='value') 塔猫
    直接看官方例子:fromflaskimportFlask,escape,url_forapp=Flask(__name__)@app.route('/')defindex():return'index'@app.route('/login')deflogin():return'login'@app.route('/user/<username&g......
  • 【Python】Flask-SQLAlchemy PyCharm无法自动补全解决方案
    ✨Flask-Sqlalchemy无法自动补全解决方案PyCharm版本:PyCharm2021.3.3(ProfessionalEdition)flask版本:2.2.3flask-sqlalchemy版本:3.0.3SQLAlchemy版本:2.0.4在使用flask-sqlalchemy中db.Column,primary_key等无法自动补全降低flask-sqlalchemy版本即可解决pipinstallf......
  • 如何在flask(烧瓶)中下载文件 塔猫PPT
    要在Flask中下载文件,您可以使用该功能。此函数采用三个参数:send_file()第一个参数是要下载的文件的路径。第二个参数是一个布尔值,指示是否要将文件作为附件下载。第三个参数是您希望文件在下载时显示的名称。例如,以下代码将从当前目录下载文件,并将其保存到用户的计算机:'fi......
  • site-packages/flask/json/init.py from future import annotations future feature a
    如果在使用Flask库时,出现了“futurefeatureannotationsisnotdefined”的错误,可能是因为Python解释器版本太低。在Python3.7及以下版本中,from__future__importannotations是不支持的,因此需要升级到Python3.8或更高版本。如果升级Python解释器版本不可行,可以......