如果我的方法有多个路由注释,如何使用url_for?

所以我有一个可以被多个路由访问的方法:

@app.route("/canonical/path/") @app.route("/alternate/path/") def foo(): return "hi!" 

现在,我怎么能调用url_for("foo")并知道我会得到第一个路线?

好。 它花了一些钻研werkzeug.routingflask.helpers.url_for代码,但我已经想通了。 您只需更改路线的endpoint (换句话说,您将路线命名

 @app.route("/canonical/path/", endpoint="foo-canonical") @app.route("/alternate/path/") def foo(): return "hi!" @app.route("/wheee") def bar(): return "canonical path is %s, alternative is %s" % (url_for("foo-canonical"), url_for("foo")) 

会产生

规范path是/规范/path/,替代是/备用/path/

这种方法有一个缺点。 Flask始终将最后定义的路由绑定到隐式定义的端点(在您的代码中为foo )。 猜猜如果重新定义端点会发生什么? 所有的url_for('old_endpoint')都会抛出werkzeug.routing.BuildError 。 所以,我想整个问题的正确解决scheme是定义规范的path最后和名称的select:

 """ since url_for('foo') will be used for canonical path we don't have other options rather then defining an endpoint for alternative path, so we can use it with url_for """ @app.route('/alternative/path', endpoint='foo-alternative') """ we dont wanna mess with the endpoint here - we want url_for('foo') to be pointing to the canonical path """ @app.route('/canonical/path') def foo(): pass @app.route('/wheee') def bar(): return "canonical path is %s, alternative is %s" % (url_for("foo"), url_for("foo-alternative")) 

Flask中的规则是独一无二的。 如果你定义了同一个函数的绝对URL,它会默认发生冲突,因为你正在做一些我们阻止你做的事情,因为从我们的angular度来看,这是错误的。

有一个原因是为什么您希望将多个URL指向绝对相同的端点,并且与过去存在的规则向后兼容。 由于WZ0.8和Flask 0.8,你可以明确地指定一个路由的别名:

 @app.route('/') @app.route('/index.html', alias=True) def index(): return ... 

在这种情况下,如果用户请求/index.html Flask将自动发出一个永久redirect到/

这并不意味着一个函数不能绑定多个url,但在这种情况下,您需要更改端点:

 @app.route('/') def index(): ... app.add_url_rule('/index.html', view_func=index, endpoint='alt_index') 

或者:

 @app.route('/') @app.route('/index.html', endpoint='alt_index') def index(): ... 

在这种情况下,您可以使用不同的名称第二次定义视图。 然而,这是你通常要避免的,因为那么视图函数将不得不检查request.endpoint来查看所谓的。 相反,更好的做这样的事情:

 @app.route('/') def index(): return _index(alt=False) @app.route('/index.html') def alt_index(): return _index(alt=True) def _index(alt): ... 

在这两种情况下,URL生成都是url_for('index')url_for('alt_index')

您也可以在路由系统级别执行此操作:

 @app.route('/', defaults={'alt': False}) @app.route('/index.html', defaults={'alt': True}) def index(alt): ... 

在这种情况下,url生成是url_for('index', alt=True)url_for('index', alt=False)

此外,对于那些使用catchvariables构造的所有路由:如果url_for传递了包含variables的字典,则Flask将正确地创buildurlpath。

例如…

app.py:

 app.route('/<path:pattern1>') app.route('/<path:pattern1>/<path:pattern2>') def catch_all(pattern1, pattern2=None): return render_template('template.html', p1=pattern1, p2=pattern2) app.route('/test') def test_routing: args = {'pattern1': 'Posts', 'pattern2': 'create'} return render_template('test.html', args=args) 

的test.html:

 <a href="{{url_for('catch_all', **args)}}">click here</a> 

当您点击“点击这里”链接时,您将被引导到“发布/创build”路线。