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"]
中
浏览器处理工作:
先判断返回状态码是否为「30x」
查看返回的头信息中是否有
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
生成静态文件
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](https://i-blog.csdnimg.cn/blog_migrate/95f75397851cf7999ba67802e77e4291.png)
http://127.0.0.1:5000/src/css/demo.css
可以看出,这个url变成了static_url_path
替换部分
跳转的时候添加参数
@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带参数跳转](https://i-blog.csdnimg.cn/blog_migrate/d99979069e92c985cfeab3c4f8a31ff4.png)
错误响应
没有任何处理的错误返回
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()
![未处理](https://i-blog.csdnimg.cn/blog_migrate/c8ef4161bf417164716f3b4f586ed80e.png)
处理500错误
@app.errorhandler(500)
def server_error(error):
return '我们正在升级'
![错误返回](https://i-blog.csdnimg.cn/blog_migrate/46298442435eeb9aab66def1dcb0914a.png)
使用官网定义的错误返回
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](https://i-blog.csdnimg.cn/blog_migrate/fdc1db2ecaaba212f44328f141fc207b.png)
使用自己的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定义错误返回](https://i-blog.csdnimg.cn/blog_migrate/00a47c2f4021292e089969ba654998d4.png)
重写官方的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()