如果我的方法有多个路由注释,如何使用url_for?
所以我有一个可以被多个路由访问的方法:
@app.route("/canonical/path/") @app.route("/alternate/path/") def foo(): return "hi!"
现在,我怎么能调用url_for("foo")
并知道我会得到第一个路线?
好。 它花了一些钻研werkzeug.routing
和flask.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”路线。