flask重定向多条路线

我正在尝试实现重定向模式,类似于StackOverflow所做的事情:

@route('/<int:id>/<username>/')

@route('/<int:id>/')

def profile(id, username=None):

user = User.query.get_or_404(id)

if user.clean_username != username:

return redirect(url_for('profile', id=id, username=user.clean_username))

return render_template('user/profile.html', user=user)

这是应该发生的情况的简单表格:

URL                         Redirects/points to

====================================================

/user/123 /user/123/clean_username

/user/123/ /user/123/clean_username

/user/123/foo /user/123/clean_username

/user/123/clean_username /user/123/clean_username

/user/123/clean_username/ /user/123/clean_username/

/user/125698 404

现在,我可以使用访问配置文件/user/1/foo,但/user/1会生成一个BuildError。我已经尝试使用alias=True关键字参数和一些东西defaults,但是我不确定什么是行不通的。

我如何将一条路由这样重定向到另一条路由?

回答:

更新:解决主要问题“我的路线出了什么问题”,最简单的调试方法是使用app.url_map;例如:

>>> app.url_map

Map([<Rule '/user/<id>/<username>/' (HEAD, OPTIONS, GET) -> profile>,

<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,

<Rule '/user/<id>/' (HEAD, OPTIONS, GET) -> profile>])

在这种情况下,这确认端点设置正确。这是同时展示Plain flask和的示例flask-classy

from app import app, models

from flask import g, redirect, url_for, render_template, request

from flask.ext.classy import FlaskView, route

@app.route('/user/<int:id>', strict_slashes=False)

@app.route('/user/<int:id>/<username>', strict_slashes=False)

def profile(id, username=None):

user = models.User.query.get_or_404(id)

if user.clean_username != username:

return redirect(url_for('profile', id=id, username=user.clean_username))

return render_template('profile.html', user=user)

class ClassyUsersView(FlaskView):

@route('/<int:id>', strict_slashes=False)

@route('/<int:id>/<username>', strict_slashes=False, endpoint='classy_profile')

def profile(self, id, username=None):

user = models.User.query.get_or_404(id)

if user.clean_username != username:

return redirect(url_for('classy_profile', id=id, username=user.clean_username))

return render_template('profile.html', user=user)

ClassyUsersView.register(app)

它们具有不同的端点,你需要考虑以下因素url_for:

>>> app.url_map

Map([<Rule '/classyusers/<id>/<username>' (HEAD, OPTIONS, GET) -> classy_profile>,

<Rule '/user/<id>/<username>' (HEAD, OPTIONS, GET) -> profile>,

<Rule '/classyusers/<id>' (HEAD, OPTIONS, GET) -> ClassyUsersView:profile_1>,

<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,

<Rule '/user/<id>' (HEAD, OPTIONS, GET) -> profile>])

没有flask-classy端点名称的是函数名称,但是如你所知,使用时这是不同的classy,你可以使用来查看端点名称,url_map()或使用来在端点名称中分配它@route(..., endpoint='name')

减少重定向:

要在最小化重定向数量的情况下响应你发布的url,你需要使用strict_slashes=False,这将确保处理未以终止的请求,/而不是通过重定向将其301重定向到以其/终止的副本:

@app.route('/user/<int:id>', strict_slashes=False)

@app.route('/user/<int:id>/<username>', strict_slashes=False)

def profile(id, username=None):

user = models.User.query.get_or_404(id)

if user.clean_username != username:

return redirect(url_for('profile', id=id, username=user.clean_username))

return render_template('profile.html', user=user)

结果如下:

>>> client = app.test_client()

>>> def check(url):

... r = client.get(url)

... return r.status, r.headers.get('location')

...

>>> check('/user/123')

('302 FOUND', 'http://localhost/user/123/johndoe')

>>> check('/user/123/')

('302 FOUND', 'http://localhost/user/123/johndoe')

>>> check('/user/123/foo')

('302 FOUND', 'http://localhost/user/123/johndoe')

>>> check('/user/123/johndoe')

('200 OK', None)

>>> check('/user/123/johndoe/')

('200 OK', None)

>>> check('/user/125698')

('404 NOT FOUND', None)

行为strict_slashes:

with strict_slashes=False

URL Redirects/points to # of redirects

===========================================================================

/user/123 302 /user/123/clean_username 1

/user/123/ 302 /user/123/clean_username 1

/user/123/foo 302 /user/123/clean_username 1

/user/123/foo/ 302 /user/123/clean_username 1

/user/123/clean_username 302 /user/123/clean_username 1

/user/123/clean_username/ 200 /user/123/clean_username/ 0

/user/125698 404

with strict_slashes=True (the default)

any non '/'-terminated urls redirect to their '/'-terminated counterpart

URL Redirects/points to # of redirects

===========================================================================

/user/123 301 /user/123/ 2

/user/123/foo 301 /user/123/foo/ 2

/user/123/clean_username 301 /user/123/clean_username/ 1

/user/123/ 302 /user/123/clean_username/ 1

/user/123/foo/ 302 /user/123/clean_username/ 1

/user/123/clean_username/ 200 /user/123/clean_username/ 0

/user/125698 404

example:

"/user/123/foo" not terminated with '/' -> redirects to "/user/123/foo/"

"/user/123/foo/" -> redirects to "/user/123/clean_username/"

我相信它完全可以满足你的测试矩阵的要求:)

以上是 flask重定向多条路线 的全部内容, 来源链接: utcz.com/qa/413299.html

回到顶部