Flask Redirects、Errors、Responses、Sessions、Message Flashing

1. redirects 和 erros

重定向到另一个请求使用 redirect() 方法;使用错误码提取结束请求使用 abort() 方法。

from flask import abort, redirect, url_for

@app.route('/')
def index():
    return redirect(url_for('login'))

@app.route('/login')
def login():
    abort(401)
    this_is_never_executed()


默认情况下都会有错误页面,如果想自定义错误页面,使用 errorhandler() 装饰器。

from flask import render_template

@app.errorhandler(404)
def page_not_found(error):
    return render_template('page_not_found.html'), 404


注意 404 在 render_template 方法后,告诉 Flask 页面 404 没有找到,默认 200。


2. responses

视图方法返回的值会自动转为一个 response 对象。如果返回值为 string, 会自动转为一个 response body 为字符串内容的 response 对象,状态码 200,和一个 text/html 的 mimetype。如果返回元组 

(response,status, headers)
 or 
(response, headers)

status 会覆盖状态码,headers 可以是一个 list 或 dict,可以携带其它的 header 值。

使用 make_response() 方法可以自行构建一个 reponse 对象。

@app.errorhandler(404)
def not_found(error):
    return render_template('error.html'), 404


@app.errorhandler(404)
def not_found(error):
    resp = make_response(render_template('error.html'), 404)
    resp.headers['X-Something'] = 'A value'
    return resp


 3. sessions

session 是在 cookies 的基础上实现的,并以加密的方式对 cookie 签名。这意味着用户可以看到 cookie 内容,但是不能修改,除非知道加密的密钥。所有使用 session 必须设置密钥。

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))


如何生成一个好的密钥:尽可能的使用随机。os.urandom(16)


4. message flashing

flashing 可以在一个请求的结束保存信息,在下一个请求访问这个信息,这需要结合 template 页面来实现。目的是提供一个友好的信息给用户。

from flask import Flask, flash, redirect, render_template, \
     request, url_for

app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != 'admin' or \
                request.form['password'] != 'secret':
            error = 'Invalid credentials'
        else:
            flash('You were successfully logged in')
            return redirect(url_for('index'))
    return render_template('login.html', error=error)


<!doctype html>
<title>My Application</title>
[ with messages = get_flashed_messages() ]
  [ if messages ]
    <ul class=flashes>
    [ for message in messages ]
      <li>[[ message ]]</li>
    [ endfor ]
    </ul>
  [ endif ]
[ endwith ]
[ block body ][ endblock ]


flashing 分类

通常分类为:message、error、info、warning,可以自定义任何类型。

flash(u'Invalid password provided', 'error')


[ with messages = get_flashed_messages(with_categories=true) ]
  [ if messages ]
    <ul class=flashes>
    [ for category, message in messages ]
      <li class="[[ category ]]">[[ message ]]</li>
    [ endfor ]
    </ul>
  [ endif ]
[ endwith ]


当 with_categories 等于 True 时,返回值是 (category, message) 元组列表。


flash message 过滤

[ with errors = get_flashed_messages(category_filter=["error"]) ]
[ if errors ]
<div class="alert-message block-message error">
  <a class="close" href="#">×</a>
  <ul>
    [- for msg in errors ]
    <li>[[ msg ]]</li>
    [ endfor -
  </ul>
</div>
[ endif ]
[ endwith ]


只显示匹配的值。

展开阅读全文