点这里获得更好的阅读体验
最近为了写一个微信小程序的后端,接触了 Flask 这个框架,阅读了官方文档和一些博文,我认为官方文档写的非常不错,很适合入门。这一周也写了很多 Flask 代码,但由于我没有系统学习过 Python,所以在阅读文档时候遇到了一些与 Python 相关的问题,在这里记录下来,可以作为对 Python 初学者阅读 Flask 文档的一种补充。
无论开发什么 Python 项目,不论其大小,都应该养成创建虚拟环境的好习惯(就像习惯使用版本控制一样),来隔离不同项目的 Python 库。在创建项目文件夹后,用下面的命令来创建并激活虚拟环境,激活后就可以安装项目需要的库了,比如 Flask!
python -m venv venv
venv\Scripts\activate
pip install Flask
下面解释一下 python -m venv venv
:
与 python main.py args
类似,python -m venv venv
执行 venv.py
这个模块,但 switch -m
允许 Python 执行不在当前目录的模块。对于可以通过 import module_name
引入的模块,大都可以通过 python -m
执行,而不用写出模块的具体路径。
在 Flask 中要为不同的 URL 编写对应的响应,可以通过装饰器实现,例如访问主页时,想要让页面显示 Hello World
:
from flask import Flask
app = Flask(__name__)
@app.route('/index')
def index():
return 'Hello World'
装饰器其实就是一种函数,更具体来说是一种高阶函数,它的返回值也是一个函数,作用是给被装饰的函数增加一些功能,比如这里的 @app.route('/index')
其实是 index = app.route('/index')(index)
的语法糖,函数 index
被传入装饰器,装饰器返回装饰后的函数并赋值给 index
。结果时,被装饰后的 index
获得了一些新的功能,例如当 /index
被访问时,执行这个 index
。
在开发时,应该开启调试模式来让一切更方便快捷,调试模式提供了热更新和一个 debugger。通过设置环境变量的方法开启调试模式:
set FLASK_ENV=development
flask run
但切记不要在生产环境中使用,因为 debugger 允许执行任意的 Python 代码。
当你想获取与客户端请求相关的东西时,你总能在 reuqest
对象里找到,例如:
request.method
request.form
,是一个字典,表单名是 key?key=value
)是 request.args.get('key', '')
request.files
,是一个字典,文件名是 keyrequest.cookies
,是一个字典查询参数是字典类型的,访问它时,最佳实践是用 get(key, default)
的方式而非 []
,这样可以避免用户的查询 key 有错时看到 400。
文件对象是继承自 Python 标准的 file
对象,FLask 为其添加了一些方法,如 save()
方法可以将文件保存到文件系统上。
Flask 在处理用户输入的问题上为我们提供了许多帮助,如在通过 Jinja 模板写 HTML 时,用户输入是会被自动转义(automatic escaping)的。但在没有使用 Jinja 模板的时候,如直接返回字符串时,我们可以通过 escape()
方法来转义:
from markupsafe import escape
ret = 'Logged in as %s' % escape(request.form['username'])
在处理用户上传的文件时,若要通过原文件名保存之,可以通过 secure_filename()
方法来防止恶意文件名:
from werkzeug.utils import secure_filename
filename = secure_filename(f.filename)
在编写一个请求的响应时,Flask 会帮助你通过返回值构造真正的 HTTP Response,但若你不满足于简单的返回字符串,HTML 或 JSON,你可以通过 make_response()
方法来修改之前的简单响应,如添加自定义 headers 或者设置 cookie,如下面的例子:
原始版本:
@app.route('/')
def index():
return render_template('index.html')
定制化:
@app.route('/')
def index():
resp = make_response(render_template('index.html'))
resp.headers['X-name'] = 'sichen'
return resp
可以看出操作方法就是把之前的返回值传入 make_response()
,然后对 response 对象进行自定义。
url_for()
而不是硬写。python -c "import os; print(os.urandom(16))"
可以生成 Flask.secret_key