上手
快速注册一个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')