什么是Flask?
FLask是一个用python编写的轻量级Web应用程序框架。Flask给予Werkzeug WSGI工具包和Jinja2模板引擎。两者都是Pocco项目。Flask也被称为"microframework",因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。
安装
依赖
当安装Flask时,以下配套软件会被自动安装。
- Werkzeug 用于实现 WSGI ,应用和服务之间的标准 Python 接口。
- Jinja 用于渲染页面的模板语言。
- MarkupSafe 与 Jinja 共用,在渲染页面时用于避免不可信的输入,防止注入攻击。
- ItsDangerous 保证数据完整性的安全标志数据,用于保护 Flask 的 session cookie.
- Click 是一个命令行应用的框架。用于提供 flask 命令,并允许添加自定义 管理命令。
虚拟环境
建议使用虚拟环境来管理项目的依赖。避免不同的项目需要不同版本的Python库等问题。 Python内置了用于创建虚拟环境的venv模块。
创建项目文件夹及虚拟环境
$ mkdir myproject
$ cd myproject
$ python3 -m venv venv
激活虚拟环境
$ . venv/bin/activate
安装Flask
$ pip install Flask
快速上手Flask
一个最小的应用
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
- 首先,我们导入了Flask类。该类的实例将会成为我们的WSGI应用。
- 接着创建一个该类的实例。第一个参数是应用模块或者包的名称。__name__是一个适用于大多数情况的快捷方式。有了这个参数,Flask才能知道在哪里可以找到模板和静态文件等东西。
- 然后使用route()装饰器来告诉Flask触发函数的URL。
- 函数返回需要在用户浏览器中显示的信息。默认的内容类型是HTML,因此字符串中的HTML会被浏览器渲染。
将其命名为”hello.py“。不要使用flask.py作为应用名称,会与Flask本身发生冲突。
运行应用
在运行应用前,需要在终端导出FLASK_APP环境变量。FLASK_APP用来说明FLask实例对象app所在的模块位置。如果你没有指定FLASK_APP环境变量,flask 运行的时候首先会尝试自动去项目的根目录下的 wsgi.py 文件 或者 app.py 文件里面去找。没找到就会报 NoAppException 错误。
(venv) liuyan@edz-20180411xol myproject % export FLASK_APP=hello
(venv) liuyan@edz-20180411xol myproject % flask run
* Serving Flask app 'hello' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
运行结果:
可以看到有个WARNING,调试器允许执行来自浏览器的任意 Python 代码。虽然它由一个 pin 保护, 但仍然存在巨大安全风险。所以,如果需要打开所有开发功能,那么在运行flask run之前设置FLASK_ENV环境变量为development。
(venv) liuyan@edz-20180411xol myproject % export FLASK_APP=hello
(venv) liuyan@edz-20180411xol myproject % export FLASK_ENV=development
(venv) liuyan@edz-20180411xol myproject % flask run
* Serving Flask app 'hello' (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 125-025-995
一些基础使用
路由
使用route()装饰器来把函数绑定到URL:
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello, World'
运行结果:
变量规则
通过把URL的一部分标记为<variable_name>就可以在URL中添加变量。标记的 部分会作为关键字参数传递给函数。通过使用 converter:variable_name ,可以 选择性的加上一个转换器,为变量指定规则。
from markupsafe import escape
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return f'User {escape(username)}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return f'Post {post_id}'
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return f'Subpath {escape(subpath)}'
运行结果:
转换器类型:
| 类型 | 说明 |
|---|---|
| string | (缺省值)接受任何不包括斜杠的文本 |
| int | 接受正整数 |
| float | 接受正浮点数 |
| path | 类似string,但可以包含斜杠 |
| uuid | 接受UUID字符串 |
HTTP方法
缺省情况下,一个路由只回应 GET 请求。 可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法:
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
运行结果:
请求对象
导入request,通过使用 method 属性可以操作当前请求方法,通过使用 form 属性处理表单数据(在 POST 或者 PUT 请求 中传输的数据)。
from flask import request
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
当 form 属性中不存在这个键时会发生什么?会引发一个 KeyError 。 如果您不像捕捉一个标准错误一样捕捉 KeyError ,那么会显示一个 HTTP 400 Bad Request 错误页面。
要操作URL(如?key=value)中提交的参数可以使用args属性:
searchword = request.args.get('key', '')
使用request接收参数:
- request.form:用于接收表单数据
- request.args:用户接收GET参数
- request.json:用户接收JSON参数
- request.value:获取所有参数(表单参数+GET参数)
- request.file:用户接收文件
- 等其他方式
关于响应
视图函数的返回值会自动转换一个响应对象。如果返回值是一个字符串,那么会被转换为一个包含作为响应体的字符串、一个200 OK出错代码和一个text/html类型的响应对象。如果返回值是一个字典,那么会调用jsonify()来产生一个响应。转换规则如下:
- 如果视图返回的是一个响应对象,那么就直接返回它。
- 如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的响应对象。
- 如果返回的是一个字典,那么调用jsonify创建一个响应对象。
- 如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少包含一个项目,且项目应当由 (response, status) 、 (response, headers) 或者 (response, status, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表 或字典。
- 如果以上都不是,那么Flask会假定返回值是一个有效的WSGI应用并把它转换成一个响应对象。