🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 导航 - [索引](# "总目录") - [下一页](# "步骤 6: 模板") | - [上一页](# "步骤 4: 请求数据库连接") | - [Flask 0.10.1 文档](#) » - [教程](#) » # 步骤 5: 视图函数 现在数据库连接已经正常工作,我们终于可以开始写视图函数了。我们一共需要写四个: ### 显示条目 这个视图显示数据库中存储的所有条目。它绑定在应用的根地址,并从数据库查询出文章的标题和正文。id 值最大的条目(最新的条目)会显示在最上方。从指针返回的行是按 select 语句中声明的列组织的元组。这对像我们这样的小应用已经足够了,但是你可能会想把它转换成字典。如果你对这方面有兴趣,请参考 [*简化查询*](#)的例子。 视图函数会将条目作为字典传递给 show_entries.html 模板,并返回渲染结果: ~~~ @app.route('/') def show_entries(): cur = g.db.execute('select title, text from entries order by id desc') entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()] return render_template('show_entries.html', entries=entries) ~~~ ### 添加条目 这个视图允许已登入的用户添加新条目,并只响应 POST 请求,实际的表单显示在show_entries 页。如果一切工作正常,我们会用 [flash()](# "flask.flash") 向下一次请求发送提示消息,并重定向回 show_entries 页: ~~~ @app.route('/add', methods=['POST']) def add_entry(): if not session.get('logged_in'): abort(401) g.db.execute('insert into entries (title, text) values (?, ?)', [request.form['title'], request.form['text']]) g.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) ~~~ 登出函数,做相反的事情,从会话中删除 logged_in 键。我们这里使用了一个简洁的方法:如果你使用字典的 [pop()](http://docs.python.org/dev/library/stdtypes.html#dict.pop "(在 Python v3.5)") [http://docs.python.org/dev/library/stdtypes.html#dict.pop] 方法并传入第二个参数(默认),这个方法会从字典中删除这个键,如果这个键不存在则什么都不做。这很有用,因为我们不需要检查用户是否已经登入。 ~~~ @app.route('/logout') def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('show_entries')) ~~~ 继续 [*步骤 6: 模板*](#) 。 © 版权所有 2013, Armin Ronacher.