3.3 KiB
在 Flask 中创建网址
最后更新于 2020 年 7 月 27 日
Flask 可以使用flask包的url_for()功能生成 URL。在模板和视图函数中硬编码 URL 是一种不好的做法。假设,我们想把我们博客的网址从/<id>/<post-title>/重组到/<id>/post/<post-title>/。如果我们的模板和视图函数中有硬编码的 URL,那么我们必须手动访问每个模板和视图函数来进行更改。然而,有了url_for()功能,像这样的改变可以很快完成。
url_for()函数接受端点,并以字符串形式返回网址。回想一下,端点指的是给 URL 的唯一名称,大多数时候它是视图函数的名称。此时,main2.py包含根(/)路由,定义如下:
#...
@app.route('/')
def index():
return render_template('index.html', name='Jerry')
#...
生成根网址调用url_for()作为url_for('index')。输出将是'/'。下面的 shell 会话演示了如何在控制台内部使用url_for()。
>>>
>>> from main2 import app
>>> from flask import url_for
>>>
>>> with app.test_request_context('/api'): # /api is arbitrarily chosen
... url_for('index')
...
'/'
>>>
请注意,我们首先创建一个请求上下文(从而隐式创建应用上下文)。试图在没有请求上下文的情况下在控制台内部使用url_for()将导致错误。您可以在这里了解更多关于申请和请求上下文的信息。
如果url_for()无法创建 URL,将抛出BuildError异常。
>>>
>>> with app.test_request_context('/api'):
... url_for('/api')
...
...
werkzeug.routing.BuildError: Could not build url for endpoint '/api
Did you mean 'static' instead?
>>>
Traceback (most recent call last):
要生成绝对网址,请将_external=True传递给url_for(),如下所示:
>>>
>>> with app.test_request_context('/api'):
... url_for('index', _external=True)
...
'http://localhost:5000/'
>>>
不要在redirect()函数中硬编码 URL,你应该总是使用url_for()来生成 URL。例如:
@app.route('/admin/')
def admin():
if not loggedin:
return redirect(url_for('login')) # if not logged in then redirect the user to the login page
return render_template('admin.html')
要为动态路由生成 URL,请将动态部分作为关键字参数传递。例如:
>>>
>>> with app.test_request_context('/api'):
... url_for('user_profile', user_id = 100)
...
'/user/100/'
>>>
>>>
>>> with app.test_request_context('/api'):
... url_for('books', genre='biography')
...
'/books/biography/'
>>>
>>>
传递给url_for()函数的额外数量的关键字参数将作为查询字符串追加到网址中。
>>>
>>> with app.test_request_context('/api'):
... url_for('books', genre='biography', page=2, sort_by='date-published')
...
'/books/biography/?page=2&sort_by=date-published'
>>>
url_for()是模板中为数不多的可用功能之一。要在模板内生成网址,只需在双花括号内调用url_for()``{{ ... }},如下所示:
<a href="{{ url_for('books', genre='biography') }}">Books</a>
输出:
<a href="/books/biography/">Books</a>