Flask上手初体验

159 阅读4分钟

上手

快速注册一个flask应用

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'hello world'

终端启动项目

flask --app 《文件名》 run

如果文件名叫app.py,上述命令可以简写

flask run

路由

使用 route() 装饰器来把函数绑定到 URL:

转换器的使用

@app.route('/user/<string:username>')
def user(username):
    return f'<h1>Hello, {username}!</h1>'

转换器的类型

string(缺省值) 接受任何不包含斜杠的文本
int接受正整数
float接受正浮点数
path类似 string ,但可以包含斜杠
uuid接受 UUID 字符串

HTTP方法

缺省情况下,一个路由只回应 GET 请求。可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法。

from flask import request

@app.route('login/<string:username>', methods=['GET', 'POST'])
def login(username):
    if request.method == 'GET':
        return f'<h1>GET, {username}, 登录成功!</h1>'
    if request.method == 'POST':
        return f'<h1>POST, {username}, 登录成功!</h1>'

上述写法将所有请求方式都放在一个方法里,你也可以把不同方法所对应的视图分别放在独立的函数中。 Flask 为每个常用 的 HTTP 方法提供了捷径,如 get()post() 等等。

@app.get('login/<string:username>')
def login_get(username):
    return f'<h1>GET, {username}, 登录成功!</h1>'


@app.post('login/<string:username>')
def login_post(username):
    return f'<h1>POST, {username}, 登录成功!</h1>'

静态文件

动态的 web 应用也需要静态文件,一般是 CSS 和 JavaScript 文件。理想情 况下您的服务器已经配置好了为您的提供静态文件的服务。但是在开发过程中, Flask 也能做好这项工作。只要在您的包或模块旁边创建一个名为 static 的文件夹就行了。静态文件位于应用的 /static 中。

project_name
	--static
	--app.py

渲染模版

使用字符串转义来生成html太过笨拙,Flask 自动为您配置了 Jinja2 模板引擎

使用 render_template() 方法可以渲染模板,您只要提供模板 名称和需要作为参数传递给模板的变量就行了

/project_name
    /app.py
    /templates
        /hello.html

app.py

from flask import render_template

@app.get('/hello')
@app.get('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

hello.html

<body>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
</body>

文件上传

前端需要在HTML 表单中设置 enctype="multipart/form-data" 属性

后端可以通过请求对象 files 属性来访问上传的文件。每个上传的文件都储 存在这个 字典 类型属性中

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/uploaded_file.txt')

Cookies

请求对象的 cookies 属性是一个包含了客户端传输 的所有 cookies 的字典。

读取 cookies:

@app.route('/')
def index():
    username = request.cookies.get('username')

储存 cookies:

@app.route('/')
def index():
    resp = make_response(render_template(...))
    resp.set_cookie('username', 'the username')
    return resp
# cookies 设置在响应对象上。通常只是从视图函数返回字符串, Flask 会把它们转换为响应对象。如果您想显式地转换,那么可以使用 make_response() 函数,然后再修改它。

重定向和错误页面

使用 redirect() 函数可以重定向。使用 abort() 可以更早退出请求,并返回错误代码:

from flask import abort, redirect, url_for

@app.route('/')
def hello_world():
    return redirect(url_for('hello'))  # 等同于 return redirect('hello.html')
# url_for:它接受视图函数的名称(endpoint)作为参数,并返回与该视图函数关联的 URL。这样做的好处是当您的应用程序的 URL 结构发生变化时,您无需手动更新每个 URL,而只需更新与之相关联的视图函数的名称。

@app.route('/home')
def home():
    abort(401)
    return ''

缺省情况下每种出错代码都会对应显示一个黑白的出错页面。使用 errorhandler() 装饰器可以定制出错页面:

@app.errorhandler(404)
def page_not_found(error):
    return render_template('page_not_found.html'), 404

关于响应

flask视图函数的返回值会自动转换为一个响应对象。

如果视图返回的是一个响应对象,那么就直接返回它。

如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于 返回的响应对象。

如果返回的是一个迭代器或者生成器,那么返回字符串或者字节,作为流 响应对待。

如果返回的是一个字典或者列表,那么使用 jsonify() 创建一个响应对象。

如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中 必须至少包含一个项目,且项目应当由 (response, status) 、 (response, headers) 或者 (response, status, headers) 组 成。 status 的值会重载状态代码, headers 是一个由额外头部 值组成的列表或字典。

如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把 它转换为一个响应对象。

JSON格式API

@app.route("/me")
def me_api():
    user = get_current_user()
    return {
        "username": user.username,
        "theme": user.theme,
        "image": url_for("user_image", filename=user.image),
    }

session

除了请求对象之外还有一种称为 session 的对象,允许您在 不同请求之间储存信息。这个对象相当于用密钥签名加密的 cookie ,即用户 可以查看您的 cookie ,但是如果没有密钥就无法修改它。

使用会话之前您必须设置一个密钥 app.secret_key

from flask import session

app = Flask(__name__)
app.secret_key = 'sklahfpwoiehrpowi":{_!(Ooihjaoqwid":'

@app.get('/index')
def index():
    if 'username' in session:
        username = session.get('username')
        return f'您已登录{username}'
    return '您未登录'


@app.route('/login/<string:username>', methods=['GET'])
def login(username):
    if request.method == 'GET':
        session['username'] = username
        return redirect(url_for('index'))


@app.get('/logout')
def logout():
    if session['username']:
        session.pop('username', None)
    return redirect(url_for('index'))

日志

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')