Flask知识点总结(一)
escape()
的作用
用户输入的数据会包含恶意代码,所以不能直接作为响应返回,需要使用 Flask
提供的 escape()
函数对 name
变量进行转义处理,比如把<
转换成 <
。这样在返回响应时浏览器就不会把它们当做代码执行。
from flask import escape
@app.route('/user/<name>')
def user_page(name):
return 'User: %s' % escape(name)
request.args.get()
方法
和普通的字典类型不同,当我们从request
对象中类型为MutliDict
或ImmutableMultiDict
的属性(比如files
、form
、args
)中直接使用键作为索引获取数据时(比如request.args['name']
),如果没有对应的键,那么会返回HTTP 400
错误响应(Bad Request
,表示请求无效),而不是抛出KeyError
异常,如下图所示。为了避免这个错误,我们应该使用get()
方法获取数据,如果没有对应的值则返回None
;get()
方法的第二个参数可以设置默认值,比如requset.args.get('name', 'Human')
。
flask routes
命令
使用flask routes
命令可以查看程序中定义的所有路由,这个列表由app.url_map
解析得到:
$ flask routes
Endpoint Methods Rule
-------- ------- -----------------------
hello GET /
static GET /static/<path:filename>
url_for()
在模板中可以直接使用
在 Python 脚本里,url_for() 函数需要从 flask 包中导入,而在模板中则可以直接使用,因为 Flask 把一些常用的函数和对象添加到了模板上下文(环境)里。
自定义命令@app.cli.command()
import click
@app.cli.command() # 注册为命令
@click.option('--drop', is_flag=True, help='Create after drop.') # 设置选项
def initdb(drop):
"""Initialize the database."""
if drop: # 判断是否输入了选项
db.drop_all()
db.create_all()
click.echo('Initialized database.') # 输出提示信息
默认情况下,函数名称就是命令的名字,现在执行 flask initdb 命令就可以创建数据库表:
$ flask initdb
使用 --drop 选项可以删除表后重新创建:
$ flask initdb --drop
模板上下文处理函数app.context_processor
对于多个模板内都需要使用的变量,我们可以使用 app.context_processor
装饰器注册一个模板上下文处理函数,如下所示:
@app.context_processor
def inject_user(): # 函数名可以随意修改
user = User.query.first()
return dict(user=user) # 需要返回字典,等同于 return {'user': user}
这个函数返回的变量(以字典键值对的形式)将会统一注入到每一个模板的上下文环境中,因此可以直接在模板中使用。
使用思路:对与从基础模板继承的模板,如果基础模板中有从后端获取的变量,那么这个变量就可以使用模板上下文处理函数注入到模板中。
jinja2模板继承中{
{ super() }}
的使用
默认的块重写行为是覆盖,如果你想向父块里追加内容,可以在子块中使用 super() 声明,即 { { super() }}。
form
表单填写注意事项
- 在
<form>
标签里使用method
属性将提交表单数据的 HTTP 请求方法指定为 POST。如果不指定,则会默认使用 GET 方法,这会将表单数据通过 URL 提交,容易导致数据泄露,而且不适用于包含大量数据的情况。 <input>
元素必须要指定name
属性,否则无法提交数据,在服务器端,我们也需要通过这个name
属性值来获取对应字段的数据。- 填写输入框标签文字的
<label>
元素不是必须的,只是为了辅助鼠标用户。当使用鼠标点击标签文字时,会自动激活对应的输入框,这对复选框来说比较有用。 for
属性填入要绑定的<input>
元素的 id 属性值。