步骤6:视图函数¶
现在数据库连接已经正常工作,我们终于可以开始写视图函数了。 你一共需要写四个:
显示条目¶
这个视图显示数据库中存储的所有条目。 它绑定在应用的根地址,并从数据库查询出文章的标题和正文。 id 值最大的条目(最新的条目)会显示在最上方。 从光标返回的行看有点像词典因为我们正在使用sqlite3.Row
行工厂函数。
视图函数会将条目作为字典传递给show_entries.html
模板,并返回渲染结果:
@app.route('/')
def show_entries():
db = get_db()
cur = db.execute('select title, text from entries order by id desc')
entries = cur.fetchall()
return render_template('show_entries.html', entries=entries)
添加新条目¶
这个视图允许已登入的用户添加新条目。它并只响应POST
请求;实际的表单显示在show_entries页。 如果一切工作正常,我们会用 flash()
向下 一次请求发送提示消息,并重定向回 show_entries 页:
@app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
db = get_db()
db.execute('insert into entries (title, text) values (?, ?)',
[request.form['title'], request.form['text']])
db.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
注意,这个视图检查用户是否登入(即,如果logged_in键在会话中存在,并且为True
)。
安全提示
确保像上面例子中一样,使用问号标记来构建 SQL 语句。 否则,当你使用格式化字符串构建 SQL 语句时,你的应用容易遭受 SQL 注入。 更多请见 在 Flask 中使用 SQLite 3 。
登入和登出¶
这些函数用来让用户登入登出。 登入通过与配置文件中的数据比较检查用户名和密码, 并设定会话中的 logged_in 键值。 如果用户成功登入,那么这个键值会被设为True
,并从定向回show_entries页。 此外,会有消息闪现来提示用户登入成功。 如果发生一个错误,模板会通知,并提示重新登录。
@app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)
logout函数,做相反的事情,从会话中删除这个键。我们这里使用了一个简洁的方法:如果你使用字典的pop()
方法并传入第二个参数(默认), 这个方法会从字典中删除这个键,如果这个键不存在则什么都不做。 这很有用,因为 我们不需要检查用户是否已经登入。
@app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
安全提示
永远不要把密码以明文形式存储在生产系统中。为简单起见,本教程使用纯文本密码。如果你计划发布基于本教程的项目,密码应该在存储到数据库或文件之前散列和加盐。
幸运的是,有Flask扩展用于哈希密码和验证密码的哈希值,因此添加此功能是相当简单的。也有许多可以用于哈希的一般 python 库。
你可以在这里找到推荐的一个Flask扩展列表。
继续步骤7:模板 。