flask 程序的基本结构

本文介绍了Flask程序的基本结构,包括初始化应用、定义路由和视图函数、程序上下文与请求上下文的概念,以及如何处理请求与响应。此外,还探讨了Flask扩展的使用,以Flask-Script为例展示了如何安装和集成扩展到Flask应用中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始化

所有的 Flask 程序都必须创建一个程序实例,web 服务器使用一种名为 web 服务器网关接口( Web Server Gateway Interface,WSGI)的协议,把接收来自客户端的所有请求都转交给这个对象处理。

from flask import Flask
    app = Flask(__name__)

app 即是实例化的 Flask 对象,Flask 类的构造函数只有一个必须的参数,就是程序主模块或者包的名字。在大多数程序中,Python 的 name 变量就是所需的值。

关于这个 __name__这里稍微提一下:

  当文件是被调用时,__name__的值为模块名;
  当文件被执行时,__name__的值为 ‘__main__’

所以,当某些文件作为模块被调用时,主程序是不会运行的,只会调用其中的类和方法等。

我们可以通过调用 run 方法启动服务器

app.run()

路由与视图

路由:当客户端把请求发送给 web 服务器时,web 服务器会再将请求发送给 Flask 程序实例,程序实例需要知道每一个 url 所请求运行的是哪部分代码,所以保存下 url 到 Python 函数的映射关系,处理 url 和函数之间关系的程序称为路由。

在 flask 程序中定义路由的最简单方式,是调用程序实例提供的 app.route 装饰器

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

这个例子便是将程序根地址 与 index 函数建立了映射关系

@app.route('/user/<name>')
def user(name):
    return '<h1>Hello %s!</h1>' % name

这是一个动态路由,name 是一个变量,符合’/user/’这个格式的路由都能由这个函数进行响应

视图:类似于 index() 这样的函数就称为视图函数,视图函数返回的响应可以是包含 HTML 的简单字符串也可以是复杂的表单等。

程序上下文,请求上下文

Flask 使用上下文临时把某些对象变为全局可访问,那么为什么要这么做呢?打个比方,一个视图函数需要访问请求对象,一般的做法当然是将这个对象作为参数传入这个视图函数。但这么做有一个弊端,如果要访问多个对象呢?一个一个地传进去吗,显然是不可能的。如果这个时候,这些需要访问的对象是全局变量,岂不是美滋滋,直接在函数中就能访问了。但能把这个作为全局变量吗?答案也是肯定的,不能,为什么呢,还是拿之前的请求函数来打比方,如果是多线程服务器,多个用户同时发起请求,那么多个线程同时处理的是不是就是多个不同的请求了,每个线程看到的请求是不会一样的,如果使用全局变量,岂不是变成一样的了,所以 Flask 使用上下文让特定的变量在一个线程中全局可访问,与此同时却又不会干扰到其他线程。

在 Flask 中有两种上下文:程序上下文,请求上下文(如下表)

变量名上下文上下文
current_app程序上下文当前激活程序的程序实例
g程序上下文处理请求时用作临时存储的对象,每次请求都会重设这个变量
request请求上下文请求对象,封装客户端发出的 http 请求中的内容
session请求上下文用户会话,用于存储请求之间需要“记住”的值的字典

上下文在使用之前需要激活(或推送)Flask 在分发请求之前激活(或推送)程序和请求上下文,请求处理完成后再将其删除。程序上下文被推送后,就可以在线程中使用 current_app 和 g 变量。请求上下文类似。但如果我们在使用这些变量之前没有激活上下文,就会导致错误(如图)。
未激活上下文
这才应该是正确的打开方式

from hello import app
from flask import current_app
app_ctx = app.app_context()
app_ctx.push()
current_app.name
'hello'
app_ctx.pop()

app_ctx.push(),push 函数将其推送,pop 函数将其删除。注意,在程序实例上调用 app.app_context() 可获得程序上下文。

请求与响应

请求调度:程序收到客户端发来的请求时,通过查询 URL 的映射关系,定位到相应的视图函数,进行处理。

响应:Flask 调用视图函数后,会将其返回值作为响应的内容。大多数情况下,响应就是一个简单的字符串,作为 HTML 页面返回客户端。

如果视图函数返回的响应需要使用不同的状态码,可以将数字编码作为第二个返回值,添加到响应文本之后。

@app.route('/')
def index():
    return '<h1>not found!</h1>'404

视图函数返回的响应其实还可以接受第三个参数,这是一个由首部(header)组成的字典,可以添加到 http 响应中。

Flask 视图函数还支持返回 Response 对象,Response 对象可以通过 make_response() 函数构造,make_response()函数可以接受 1 ,2 ,3 个参数(和视图函数的返回值一样)

from flask import make_response

@app.route('/')
def index():
    response = make_response('<h1>This document carries a cookie!</h1>')
    response.set_cookie('answer','42')
    return response

重定向:一种特殊的响应类型,这种响应没有页面文档,只告诉浏览器一个新地址用于加载新页面,重定向经常使用 302 状态码表示,指向的地址由 Location 首部提供(这个 Location 首部是啥?)。重定向可以使用三个值形式的返回值生成,也可以在 Response 对象中设定。

Flask 提供了 redirect() 辅助函数,用于生成重定向响应

from flask import redirect

@app.route('/')
def index():
    return redirect('http://www.example.com')

还有一种特殊的响应由 abort 函数生成,用于处理错误

from flask import abort

@app.route('/user/<id>')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return '<h1>Hello,%s</h1>' % user.name

这个例子中,如果没有查询 id 所对应的 User 则抛出一个 404 的错误信息

注意,abort 不会吧控制权交还给调用它的函数,而是抛出异常把控制权交给了 web 服务器

Flask扩展

Flask 被设计为可扩展形式,开发者可以自由选择最适合程序的包,或者按需求自行开发。这里以添加 Flask-Script 为例进行阐述如何进行扩展。Flask-Script是一个 Flask 扩展,为 Flask 添加了一个命令行解释器。

  • 使用 pip 安装该扩展

pip install flask-script

  • 使用 Flask-Script
from flask import Flask
from flask_script import Manager

app = Flask(__name__)

manager = Manager(app)

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

把程序实例作为参数传给构造函数,初始化主类的实例。这个扩展的初始化方法对于很多扩展都适用。

注意:专门为 Flask 开发的扩展都暴露在 flask.ext 命名空间下(这是书上的原话,但不知为何,我不能从那个命名空间中导出来;就好比上面那个例子,是从 flask_script 中导出)。

声明:本文乃是本人学习笔记,很多内容来自于 Grinberg 的《Flask web 开发》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值