Flask(重定向和錯誤響應 六)

redirect(重定向)實現方式

from flask imports redirect

@app.route('/')
def index():
    if request.args.get('username') is None:
        return redirect('login')
    return 'hello'

源碼

def redirect(location, code=302, Response=None):
    if Response is None:
        from .wrappers import Response

    display_location = escape(location)
    if isinstance(location, text_type):
        from .urls import iri_to_uri

        location = iri_to_uri(location, safe_conversion=True)
    response = Response(
        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
        "<title>Redirecting...</title>\n"
        "<h1>Redirecting...</h1>\n"
        "<p>You should be redirected automatically to target URL: "
        '<a href="%s">%s</a>.  If not click the link.'
        % (escape(location), display_location),
        code,
        mimetype="text/html",
    )
    response.headers["Location"] = location
    return response
  • 重定向的code默認爲302

  • 我們傳入的第一個參數location被放入到了response.headers["Location"]

瀏覽器處理工作:

  1. 先判斷返回狀態碼是否爲「30x」

  2. 查看返回的頭信息中是否有Location字段,如果有則訪問新的網址

重定向的兩種方式

redirect('/new/url')

不建議使用:url地址可能會發生變更,函數名變更比較少

redirect(url_for('endpoint'))

@app.route('/')
def index():
    if request.args.get('username') is None:
        return redirect(url_for('login'))
    return 'hello'


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

url_for

  1. 生成靜態文件

url_for('static',filename='style.css')

例子:

from flask import Flask, render_template

app = Flask(__name__, static_url_path='/src')


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


if __name__ == '__main__':
    app.run()

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="{{ url_for('static',filename='css/demo.css') }}">
    <title>Title</title>
</head>
<body>
<p>hello</p>
</body>
</html>

static/css/demo.css

.p {
    color: red;
}
css_url

http://127.0.0.1:5000/src/css/demo.css可以看出,這個url變成了static_url_path替換部分

  1. 跳轉的時候添加參數

@app.route('/')
def index():
    if request.args.get('username') is None:
        return redirect(url_for('login', username='zhongxin'))
    return 'hello'


@app.route('/login', endpoint='login')
def login():
    return 'login'

訪問:http://127.0.0.1:5000/

會跳轉到:http://127.0.0.1:5000/login?username=zhongxin

url_for帶參數跳轉

錯誤響應

沒有任何處理的錯誤返回

from flask import Flask, render_template

app = Flask(__name__, static_url_path='/src')


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


if __name__ == '__main__':
    app.run()
未處理

處理500錯誤

@app.errorhandler(500)
def server_error(error):
    return '我們正在升級'
錯誤返回

使用官網定義的錯誤返回

from flask import Flask, render_template, request, abort

app = Flask(__name__, static_url_path='/src')


@app.route('/')
def index():
    if not request.args.get('username'):
        abort(401)
    return render_template('index.html')


if __name__ == '__main__':
    app.run()
官網定義的401

使用自己的html定義錯誤返回

from flask import Flask, render_template, request, abort, make_response

app = Flask(__name__, static_url_path='/src')


@app.route('/')
def index():
    if not request.args.get('username'):
        abort(make_response(render_template('user_error_404.html'), 404))
    return render_template('index.html')


if __name__ == '__main__':
    app.run()
自己的html定義錯誤返回

重寫官方的404錯誤

from flask import Flask, render_template, request, abort, make_response

app = Flask(__name__, static_url_path='/src')


@app.errorhandler(404)
def server_error(error):
    return render_template('user_error_404.html')


@app.route('/')
def index():
    if not request.args.get('username'):
        abort(404)
    return render_template('index.html')


if __name__ == '__main__':
    app.run()

abort源碼

def abort(status, *args, **kwargs):
    return _aborter(status, *args, **kwargs)


_aborter = Aborter()

其實就是調用Aborter

class Aborter(object):
    def __init__(self, mapping=None, extra=None):
        if mapping is None:
            mapping = default_exceptions
        self.mapping = dict(mapping)
        if extra is not None:
            self.mapping.update(extra)

    def __call__(self, code, *args, **kwargs):
        if not args and not kwargs and not isinstance(code, integer_types):
            raise HTTPException(response=code)
        if code not in self.mapping:
            raise LookupError("no exception for %r" % code)
        raise self.mapping[code](*args, **kwargs)

執行的時候就是__call__會拋出異常

其實,它就是拋出一個異常而已

自己創建錯誤信息類

from flask import Flask, render_template, request

app = Flask(__name__, static_url_path='/src')


class UserError(Exception):
    pass


@app.errorhandler(UserError)
def server_error(error):
    return render_template('user_error_404.html', error=error)


@app.route('/')
def index():
    if not request.args.get('username'):
        raise UserError()
    return render_template('index.html')


if __name__ == '__main__':
    app.run()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章