烧瓶重写 url

Flask rewrite url

我正在做一个从 tmdb's API.

中提取数据的小项目

现在我有一个 /tv 视图,它接受一个 ID 并请求与该 ID 关联的电视节目。它会产生一个 url 样例。com/tv/23521。查看 tmdb 自己的站点,他们的 URL 结构似乎类似于 "id-slug-title"。不管 ID 后面是什么,它仍然会将您重定向到正确的页面。

这是怎么做到的?它似乎接受 URL,将其拆分为“-”并使用第一个参数作为 ID。不过,我不确定如何在 Flask 中做到这一点。我正在考虑使用前后请求方法,但我担心这只会进行不必要的 API 调用。为了获得 slug 标题,我必须至少使用 ID 进行一次调用以获取标题,然后对该标题进行 slugify。

路由接受 id 和 slug,其中 slug 是可选的:

@app.route('/tv/<int:id>', defaults={'slug': None})
@app.route('/tv/<int:id>-<slug>')
def tv(id, slug):
    # ...

请注意,您不必自己进行任何拆分;如果有一个整数后跟一个破折号和更多文本,或者如果它只是一个数字,则路由匹配。

只需要 id 参数 即可找到正确的页面。 slug 只是根据 'canonical' 进行检查,如果不匹配,您将被重定向:

page = load_page(id)
if slug != page.slug:
    return redirect(url_for('tv', id=id, slug=page.slug))

不要每次都重新计算 slug,只需将其存储在数据库中即可。您必须无论如何加载页面信息才能提供服务。

您可以将该行为放在装饰器中,并将加载的页面数据传递到视图中:

@app.route('/tv/<int:id>', defaults={'slug': None})
@app.route('/tv/<int:id>-<slug>')
@tv_page
def tv(page):
    # ...

with tv_page 然后处理参数:

from functools import wraps

def tv_page(view_func):
    @wraps(view_func)
    def wrapper(id, slug):
        page = load_page(id)
        if slug != page.slug:
            return redirect(url_for('tv', id=id, slug=page.slug))
        return view_func(page)
    return wrapper