请求、重定向及会话

Web 开发中经常需要处理 HTTP 请求、重定向和会话等诸多事务,相应地,Flask 也内建了一些常见的对象如 request, session, redirect 等对它们进行处理。

请求对象 request

HTTP 请求方法有 GET、POST、PUT 等,request 对象也相应地提供了支持。举个例子,假设现在我们开发一个功能:用户注册。如果 HTTP 请求方法是 POST,我们就注册该用户,如果是 GET 请求,我们就显示注册的字样。代码示例如下(注意,下面代码并不能直接运行,文末提供了完整的代码):

  1. from flask import Flask, request
  2. app = Flask(__name__)
  3. @app.route('/register', methods=['POST', 'GET']):
  4. def register():
  5. if request.method == 'GET':
  6. return 'please register!'
  7. elif request.method == 'POST':
  8. user = request.form['user']
  9. return 'hello', user

重定向对象 redirect

当用户访问某些网页时,如果他还没登录,我们往往会把网页重定向到登录页面,Flask 提供了 redirect 对象对其进行处理,我们对上面的代码做一点简单的改造,如果用户注册了,我们将网页重定向到首页。代码示例如下:

  1. from flask import Flask, request, redirect
  2. app = Flask(__name__)
  3. @app.route('/home', methods=['GET']):
  4. def index():
  5. return 'hello world!'
  6. @app.route('/register', methods=['POST', 'GET']):
  7. def register():
  8. if request.method == 'GET':
  9. return 'please register!'
  10. elif request.method == 'POST':
  11. user = request.form['user']
  12. return redirect('/home')

会话对象 session

程序可以把数据存储在用户会话中,用户会话是一种私有存储,默认情况下,它会保存在客户端 cookie 中。Flask 提供了 session 对象来操作用户会话,下面看一个示例:

  1. from flask import Flask, request, session, redirect, url_for, render_template
  2. app = Flask(__name__)
  3. @app.route('/home', methods=['GET'])
  4. def index():
  5. return 'hello world!'
  6. @app.route('/register', methods=['GET', 'POST'])
  7. def register():
  8. if request.method == 'POST':
  9. user_name = request.form['user']
  10. session['user'] = user_name
  11. return 'hello, ' + session['user']
  12. elif request.method == 'GET':
  13. if 'user' in session:
  14. return redirect(url_for('index'))
  15. else:
  16. return render_template('login.html')
  17. app.secret_key = '123456'
  18. if __name__ == '__main__':
  19. app.run(host='127.0.0.1', port=5632, debug=True)

操作 session 就像操作 python 中的字典一样,我们可以使用 session['user'] 获取值,也可以使用 session.get('user') 获取值。注意到,我们使用了 url_for 生成 URL,比如 /home 写成了 url_for('index')url_for() 函数的第一个且唯一必须指定的参数是端点名,即路由的内部名字。默认情况下,路由的端点是相应视图函数的名字,因此 /home 应该写成 url_for('index')。还有一点,使用session 时要设置一个密钥 app.secret_key

附录

本节完整的代码如下:

  1. $ tree .
  2. .
  3. ├── flask-session.py
  4. └── templates
  5. ├── layout.html
  6. └── login.html
  7. $ cat flask-session.py
  8. from flask import Flask, request, session, redirect, url_for, render_template
  9. app = Flask(__name__)
  10. @app.route('/')
  11. def head():
  12. return redirect(url_for('register'))
  13. @app.route('/home', methods=['GET'])
  14. def index():
  15. return 'hello world!'
  16. @app.route('/register', methods=['GET', 'POST'])
  17. def register():
  18. if request.method == 'POST':
  19. user_name = request.form['user']
  20. session['user'] = user_name
  21. return 'hello, ' + session['user']
  22. elif request.method == 'GET':
  23. if 'user' in session:
  24. return redirect(url_for('index'))
  25. else:
  26. return render_template('login.html')
  27. app.secret_key = '123456'
  28. if __name__ == '__main__':
  29. app.run(host='127.0.0.1', port=5632, debug=True)
  30. $ cat layout.html
  31. <!doctype html>
  32. <title>Hello Sample</title>
  33. <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
  34. <div class="page">
  35. {% block body %}
  36. {% endblock %}
  37. </div>
  38. $ cat login.html
  39. {% extends "layout.html" %}
  40. {% block body %}
  41. <form name="register" action="{{ url_for('register') }}" method="post">
  42. Hello {{ title }}, please login by:
  43. <input type="text" name="user" />
  44. </form>
  45. {% endblock %}