烧瓶重写网址

Posted

技术标签:

【中文标题】烧瓶重写网址【英文标题】:Flask rewrite url 【发布时间】:2016-04-02 06:57:54 【问题描述】:

我正在做一个从tmdb's API 提取数据的小项目。

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

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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):
    # ...

使用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

【讨论】:

以上是关于烧瓶重写网址的主要内容,如果未能解决你的问题,请参考以下文章

旧网址的网址重写不起作用

网址重写规则错误:在此服务器上找不到请求的网址

帖子/类别网址重写htaccess相同的网址级别

网址重写与路由

PHP .htaccess重写网址

如何从烧瓶中调用另一个 web 服务 api