最简单的应用结构如下,我们一一来剖析

  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def index():
  5. return "hello world"

初始化

所有Flask应用都必须创建一个应用实例,接收处理来自客户端的请求。初始化应用,必须传入一个参数,即应用主模块或包的名称,来确定应用的位置,进而找到应用中其他文件的位置,例如图像和模板

  1. from flask import Flask
  2. app = 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”

  1. - 通过app.add_url_route(url, 端点, 视图函数)
  2. ```python
  3. from flask import Flask
  4. app = Flask(__name__)
  5. def index():
  6. return "hello world"
  7. app.add_url_route('/', 'index', index)

动态路由

许多业务中,地址中都包含可变的部分,比如用户id,用户名的数据,这就是动态路由。

  • 动态路由的工作流

路由URL中放在尖括号里的内容就是动态部分,任何能匹配静态部分的URL都会映射到这个路由上。调用视图函数时,Flask会将动态部分作为参数传入函数。在这个视图函数中,name参数用于生成个性化的欢迎消息。

  • 动态路由的参数类型、

string、int、float、path。默认类型为string,path中可以包含”/“

  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route("/<name>")
  4. def index(name):
  5. return "hello %s" %name
  6. @app.route("/user/<int:id>")
  7. def int(id):
  8. return "hello %s" %id
  9. @app.route("/user/<float:id>")
  10. def float(id):
  11. return "hello %s" %id
  12. @app.route("/user/<path:mypath>")
  13. def path(mypath):
  14. return "hello %s" %mypath

查看映射关系

可以通过app.url_map查看URL映射关系表

  1. $python
  2. from hello import app
  3. app.url_map

image.png

设置请求方法

路由中未传入method时,默认支持的请求为HEAD、GET、OPTIONS。
执行methos后,会根据请求的方法,做出相应的逻辑处理。

  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route("/methods", methods=["GET", "POST"])
  4. def method():
  5. if request.method == "POST":
  6. return "POST方法"
  7. return "get方法"
  • get方法

image.png

  • post方法

    image.png

    根据视图函数获取url

    url_for()最简单的方法是,以视图函数名作为参数,返回对应的URL

    1. @app.route("/user/<name>")
    2. def user(name):
    3. return render_template("user.html")
  • 相对地址,默认

    1. url_for('index') # "/"
  • 绝对地址,需要增加_external=True

    1. url_for('index', _external=True) # "http://localhost:5000/"
  • 动态路由参数、非动态路由参数

    1. url_for('user', name="test", _external=True) # "http://localhost:5000/user/test"
    2. 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()

  1. 通过编程方式启动时,还可以添加启动参数,比如指定调试模式,hostport等。如下程序就开启调试模式,并将host绑定至0.0.0.0,这样同一网络下的其他用户,就可以通过 本机 ip+port 访问到我们的应用。
  2. ```powershell
  3. from flask import Flask
  4. app = Flask(__name__)
  5. @app.route("/")
  6. def index():
  7. return "hello world"
  8. if __name__ == "__main__":
  9. app.run(debug=True, host=0.0.0.0, port=5050)

命令行方式启动

可以通过flask run 来启动我们的程序,不过在此之前,我们要指定应用实例

  • windows

    1. set FLASK_APP=hello.py
    2. flask run
  • linux

    1. export FLASK_APP=hello.py
    2. flask 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.

  1. ```powershell
  2. $flask run --help
  3. Usage: flask run [OPTIONS]
  4. Run a local development server.
  5. This server is for development purposes only. It does not provide the
  6. stability, security, or performance of production WSGI servers.
  7. The reloader and debugger are enabled by default if FLASK_ENV=development
  8. or FLASK_DEBUG=1.
  9. Options:
  10. -h, --host TEXT The interface to bind to.
  11. -p, --port INTEGER The port to bind to.
  12. --cert PATH Specify a certificate file to use HTTPS.
  13. --key FILE The key file to use when specifying a
  14. certificate.
  15. --reload / --no-reload Enable or disable the reloader. By default
  16. the reloader is active if debug is enabled.
  17. --debugger / --no-debugger Enable or disable the debugger. By default
  18. the debugger is active if debug is enabled.
  19. --eager-loading / --lazy-loading
  20. Enable or disable eager loading. By default
  21. eager loading is enabled if the reloader is
  22. disabled.
  23. --with-threads / --without-threads
  24. Enable or disable multithreading.
  25. --extra-files PATH Extra files that trigger a reload on change.
  26. Multiple paths are separated by ';'.
  27. --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页面回送客户端。
响应形式可以为几个参数组成的元祖形式(以上都是该形式)、响应对象、或者模板

  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def index():
  5. return "hello world"
  6. @app.route("/bad-request")
  7. def bad_request():
  8. return "bad_request", 400
  9. @app.route("/template")
  10. def template():
  11. from flask import render_template
  12. return render_template("template.html", key=value) #key为模板中接收的变量名,value为变量值

响应状态码

视图函数返回响应时,不指定状态码,则默认200。如果需要指定状态码,就在第二个参数返回状态数字码

  1. from flask import Flask
  2. app = Flask(__name__)
  3. @app.route("/bad-request")
  4. def bad_request():
  5. return "bad_request", 400

image.png

响应对象

属性或方法 说明
status_code HTTP数字状态码
headers 一个类似字典的对象,包含随响应发送的所有头部
set_cookies() 为响应添加一个cookie
delete_cookie() 删除一个cookie
content_length 响应主体长度
content_type 响应主题的媒体类型
set_data() 使用字符串或字节值设定响应
get_data() 获取响应主体

特殊响应

重定向

重定向响应可以使用3个值形式的返回值生成,也可在响应对象中设定。不过,由于使用频繁,Flask提供了redirect()辅助函数

  1. from flask import Flask, redirect
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def index():
  5. return redirxt("https://www.baidu.com")

abort

还有一种特殊的响应由abort()函数生成,用于处理错误。
abort()不会把控制权交还给调用它的函数,而是抛出异常

  1. from flask import Flask, abort
  2. app = Flask(__name__)
  3. @app.route("/")
  4. def index():
  5. abort(404)