Flask基础教程

513 阅读5分钟

什么是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>"
  1. 首先,我们导入了Flask类。该类的实例将会成为我们的WSGI应用。
  2. 接着创建一个该类的实例。第一个参数是应用模块或者包的名称。__name__是一个适用于大多数情况的快捷方式。有了这个参数,Flask才能知道在哪里可以找到模板和静态文件等东西。
  3. 然后使用route()装饰器来告诉Flask触发函数的URL。
  4. 函数返回需要在用户浏览器中显示的信息。默认的内容类型是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)

运行结果:

281635322429_.pic.jpg

可以看到有个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'

运行结果: image.png image.png

变量规则

通过把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)}'

运行结果: image.png

image.png

image.png 转换器类型:

类型说明
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()

运行结果: image.png

image.png

请求对象

导入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()来产生一个响应。转换规则如下:

  1. 如果视图返回的是一个响应对象,那么就直接返回它。
  2. 如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的响应对象。
  3. 如果返回的是一个字典,那么调用jsonify创建一个响应对象。
  4. 如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少包含一个项目,且项目应当由 (response, status) 、 (response, headers) 或者 (response, status, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表 或字典。
  5. 如果以上都不是,那么Flask会假定返回值是一个有效的WSGI应用并把它转换成一个响应对象。