最简单的应用结构如下,我们一一来剖析
from flask import Flaskapp = Flask(__name__)@app.route("/")def index():return "hello world"
初始化
所有Flask应用都必须创建一个应用实例,接收处理来自客户端的请求。初始化应用,必须传入一个参数,即应用主模块或包的名称,来确定应用的位置,进而找到应用中其他文件的位置,例如图像和模板
from flask import Flaskapp = Flask(__name__)
路由和视图函数
处理URL函数之间的关系的程序称为路由。
请求分发流程:客户端把请求发送给Web服务器,Web服务器再把请求发送给Flask应用实例。应用实例需要知道对每个URL的请求要运行哪些代码,所以保存了一个URL到Python函数的映射关系
视图函数:如上index()这样,处理入站请求的函数称为视图函数,其主要功能生成请求的响应。
响应可以为包含HTML的简单字符串,也可以是复杂表单。
注册路由
- 通过app.route(url)装饰器—常用的方法. ```python from flask import Flask app = Flask(name)
@app.route(“/“) def index(): return “hello world”
- 通过app.add_url_route(url, 端点, 视图函数)```pythonfrom flask import Flaskapp = Flask(__name__)def index():return "hello world"app.add_url_route('/', 'index', index)
动态路由
许多业务中,地址中都包含可变的部分,比如用户id,用户名的数据,这就是动态路由。
- 动态路由的工作流
路由URL中放在尖括号里的内容就是动态部分,任何能匹配静态部分的URL都会映射到这个路由上。调用视图函数时,Flask会将动态部分作为参数传入函数。在这个视图函数中,name参数用于生成个性化的欢迎消息。
- 动态路由的参数类型、
string、int、float、path。默认类型为string,path中可以包含”/“
from flask import Flaskapp = Flask(__name__)@app.route("/<name>")def index(name):return "hello %s" %name@app.route("/user/<int:id>")def int(id):return "hello %s" %id@app.route("/user/<float:id>")def float(id):return "hello %s" %id@app.route("/user/<path:mypath>")def path(mypath):return "hello %s" %mypath
查看映射关系
可以通过app.url_map查看URL映射关系表
$pythonfrom hello import appapp.url_map
设置请求方法
路由中未传入method时,默认支持的请求为HEAD、GET、OPTIONS。
执行methos后,会根据请求的方法,做出相应的逻辑处理。
from flask import Flaskapp = Flask(__name__)@app.route("/methods", methods=["GET", "POST"])def method():if request.method == "POST":return "POST方法"return "get方法"
- get方法

-

根据视图函数获取url
url_for()最简单的方法是,以视图函数名作为参数,返回对应的URL
@app.route("/user/<name>")def user(name):return render_template("user.html")
相对地址,默认
url_for('index') # "/"
绝对地址,需要增加_external=True
url_for('index', _external=True) # "http://localhost:5000/"
动态路由参数、非动态路由参数
url_for('user', name="test", _external=True) # "http://localhost:5000/user/test"url_for('user', name="test", page=2, version=1) "/user/test?page=2&version=1"
URL组成解析
就以下面这个URL为例,介绍下普通URL的各部分组成
http://www.baidu.com:80/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:
1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在”HTTP”后面的“//”为分隔符
2.域名部分:该URL的域名部分为“www.baidu.com”。一个URL中,也可以使用IP地址作为域名使用
3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符程序启动
一个简单的应用中,包含一个应用实例、一个路由、一个视图函数。Flask应用Web开发服务器。
现在来启动我们编写好的应用。启动后默认服务地址为http://localhost:5000/编程方式启动
hello.py ```python from flask import Flask app = Flask(name)
@app.route(“/“) def index(): return “hello world”
if name == “main“: app.run()
通过编程方式启动时,还可以添加启动参数,比如指定调试模式,host、port等。如下程序就开启调试模式,并将host绑定至0.0.0.0,这样同一网络下的其他用户,就可以通过 本机 ip+port 访问到我们的应用。```powershellfrom flask import Flaskapp = Flask(__name__)@app.route("/")def index():return "hello world"if __name__ == "__main__":app.run(debug=True, host=0.0.0.0, port=5050)
命令行方式启动
可以通过flask run 来启动我们的程序,不过在此之前,我们要指定应用实例
windows
set FLASK_APP=hello.pyflask run
linux
export FLASK_APP=hello.pyflask run
调试模式
Flask应用可以在调试模式中运行。在这个模式下,开发服务器默认会加载两个便利的工具:重载器和调试器。
重载器:启动重载器后,开发过程中修改代码后,服务会自动重启,使改动生效。
调试器:当应用抛出未处理的异常时,它会出现在浏览器中。此时,Web浏览器变成一个交互式栈跟踪,你可以在里面审查源码,在调用栈的任何位置计算表达式命令行选项
通过命令行运行应用时,可以通过命令行参数设置一些启动参数,比如是否开启调试模式()、指定host、端口号、运行的环境等。 ```powershell $flask —help Usage: flask [OPTIONS] COMMAND [ARGS]…
A general utility script for Flask applications.
Provides commands from Flask, extensions, and the application. Loads the application defined in the FLASK_APP environment variable, or from a wsgi.py file. Setting the FLASK_ENV environment variable to ‘development’ will enable debug mode.
set FLASK_APP=hello.py set FLASK_ENV=development flask run
Options: —version Show the flask version —help Show this message and exit.
Commands: db Perform database migrations. routes Show the routes for the app. run Run a development server. shell Run a shell in the app context.
```powershell$flask run --helpUsage: flask run [OPTIONS]Run a local development server.This server is for development purposes only. It does not provide thestability, security, or performance of production WSGI servers.The reloader and debugger are enabled by default if FLASK_ENV=developmentor FLASK_DEBUG=1.Options:-h, --host TEXT The interface to bind to.-p, --port INTEGER The port to bind to.--cert PATH Specify a certificate file to use HTTPS.--key FILE The key file to use when specifying acertificate.--reload / --no-reload Enable or disable the reloader. By defaultthe reloader is active if debug is enabled.--debugger / --no-debugger Enable or disable the debugger. By defaultthe debugger is active if debug is enabled.--eager-loading / --lazy-loadingEnable or disable eager loading. By defaulteager loading is enabled if the reloader isdisabled.--with-threads / --without-threadsEnable or disable multithreading.--extra-files PATH Extra files that trigger a reload on change.Multiple paths are separated by ';'.--help Show this message and exit.
请求
上下文
| 变量名 | 说明 |
|---|---|
| current_app | 应用上下文。当前应用的应用实例 |
| g | 应用山下文。处理请求时用作临时存储的对象,每次请求都会重设这个变量 |
| request | 请求上下文。请求对象,封装了客户端发出的HTTP请求中的内容 |
| session | 请求上下文,用户会话,值为一个字典,存储请求之间需要记住的值 |
请求对象
Flask通过上下文变量request对外开放请求对象。包含客户端发送的HTTP请求的全部信息
| 属性或方法 | 说明 | 示例 |
|---|---|---|
| method | HTTP请求方法,GET、POST、DELETE等 | |
| url | 客户端请求的完整URL | https://www.baidu.com/test?a=1 |
| base_url | 同url,但是没有查询字符串部分 | https://www.baidu.com/test |
| path | URL的路径部分 | test |
| query_string | url的查询字符串部分,返回原始二进制 | a=1 |
| full_path | url的路径和查询字符串部分 | test?a=1 |
| form | 一个字典,存储请求提交的所有表单字段 | |
| args | 一个字典,村塾通过URL查询字符串传递的所有参数 | |
| values | 一个字典,form和args的合集 | |
| cookies | 一个字典,存储请求的所有cookie | |
| headers | 一个字典,存储请求的所有HTTP头部 | |
| files | 一个字典,存储请求上传的所有文件 | |
| get_data() | 返回请求主题缓冲的数据 | |
| get_json() | 返回一个python字典,包含解析请求主体后得到的JSON | |
| blueprint | 处理请求的Flask蓝本名称 | |
| endpoint | 处理请求的Flask端点名称;Flask把视图函数的名称用作路由端点的名称 | |
| scheme | URL方案,http或者https | |
| is_secures() | HTTPS,返回True | |
| remote_addr | 客户端ip | |
| environ | 请求的原始WSGI环境字典 |
请求钩子
有时在处理请求之前或之后执行代码会很有用。例如,在请求开始时,我们可能需要创建数据库连接或者验证发起请求的用户身份。为了避免在每个视图函数中都重复编写代码,Flask提供了注册通用函数的功能,注册的函数可在请求被分派到视图函数之前或之后调用.
| 名称 | 说明 |
|---|---|
| before_request | 注册一个函数,每次请求之前运行 |
| before_first_request | 注册一个函数,只在处理第一个请求之前运行。 可以通过这个钩子添加服务器初始化任务 |
| after_request | 注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行 |
| teardown_request | 注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行 |
在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g。例如,before request处理程序可以从数据库中加载已登录用户,并将其保存到g.user中。随后调用视图函数时,便可以通过g.user获取用户
响应
Flask调用视图函数后,会将其返回值作为响应的内容。多数情况下,响应就是一个简单的字符串,作为HTML页面回送客户端。
响应形式可以为几个参数组成的元祖形式(以上都是该形式)、响应对象、或者模板
from flask import Flaskapp = Flask(__name__)@app.route("/")def index():return "hello world"@app.route("/bad-request")def bad_request():return "bad_request", 400@app.route("/template")def template():from flask import render_templatereturn render_template("template.html", key=value) #key为模板中接收的变量名,value为变量值
响应状态码
视图函数返回响应时,不指定状态码,则默认200。如果需要指定状态码,就在第二个参数返回状态数字码
from flask import Flaskapp = Flask(__name__)@app.route("/bad-request")def bad_request():return "bad_request", 400
响应对象
| 属性或方法 | 说明 |
|---|---|
| status_code | HTTP数字状态码 |
| headers | 一个类似字典的对象,包含随响应发送的所有头部 |
| set_cookies() | 为响应添加一个cookie |
| delete_cookie() | 删除一个cookie |
| content_length | 响应主体长度 |
| content_type | 响应主题的媒体类型 |
| set_data() | 使用字符串或字节值设定响应 |
| get_data() | 获取响应主体 |
特殊响应
重定向
重定向响应可以使用3个值形式的返回值生成,也可在响应对象中设定。不过,由于使用频繁,Flask提供了redirect()辅助函数
from flask import Flask, redirectapp = Flask(__name__)@app.route("/")def index():return redirxt("https://www.baidu.com")
abort
还有一种特殊的响应由abort()函数生成,用于处理错误。
abort()不会把控制权交还给调用它的函数,而是抛出异常
from flask import Flask, abortapp = Flask(__name__)@app.route("/")def index():abort(404)


