【问题标题】:Having the view function – how do I get the URL of a Blueprint route in Flask?拥有视图功能——如何在 Flask 中获取蓝图路由的 URL?
【发布时间】:2016-01-13 11:06:28
【问题描述】:

我使用的缓存系统 (Flask-Cache) 使用 URL 来计算缓存键。我从代码中的不同位置传递了一个视图函数,然后需要检查视图是否已被缓存。

首先,Flask-Cache 的当前迭代需要计算缓存键的请求,但我做了一个patch,通过获取带有url_for(view_function.__name__, **kwargs) 的URL 来解决简单情况的不足。

问题是现在我已经开始使用Flask Blueprints,而在url_for 中简单地使用view_function.__name__ 将找不到蓝图路由(引发BuildError)。

简单的 Flask 应用

@app.route('/user/<user_id>')
def user_page(user_id):
    return 'Hello user %s' % user_id

def check_cache(view_function, **kwargs):
    url = url_for(view_function.__name__, **kwargs)
    ... use URL to check cache ...

check_cache(user_page, user_id='123')

Blueprint Flask 应用程序

from flask import Blueprint    

bp = Blueprint('user_blueprint', __name__)

@bp.route('/user/<user_id>')
def user_page(user_id):
    return 'Hello user %s' % user_id

def check_cache(view_function, **kwargs):
    url = url_for(view_function.__name__, **kwargs) # WON'T WORK WITH BLUEPRINTS
    ... use URL to check cache ...

check_cache(user_page, user_id='123')

如何获取通过蓝图定义的路由/视图函数的 URL?

或者,我如何制作在使用蓝图时有效的缓存键? (并且可以通过视图函数上的装饰器计算,当两个或多个蓝图具有相同名称的视图函数时不会发生冲突)

【问题讨论】:

标签: flask


【解决方案1】:

默认情况下,蓝图会在端点名称前加上蓝图名称。这样,url_for 字符串:

url = url_for('user_page')

变成:

url = url_for('user_blueprint.user_page')

现在,您正在使用函数名称创建 url_for 字符串,因此您可以切换到显式传递上述端点字符串,或者使用:

url = url_for('user_blueprint.' + view_function.__name__)

我不知道从 view_function 中自动查找蓝图名称的编程方式。

【讨论】:

  • 最后一行正是我的问题:在Flask-Cache里面,不知道view函数属于哪个蓝图。如果request 可用,您似乎可以通过current_app.blueprints[request.blueprint] 获得蓝图,但在我的用例中request 不可用(参考:librelist.com/browser/flask/2012/4/7/current-blueprint/…
  • 为什么不能直接切换到使用 url_for 字符串?那么你的 check_cache 会变成 check_cache(url_for_string, **kwargs): url = url_for(url_for_string) ...
  • Flask-Cache 使用装饰器(通常以@app.cache.cached 调用),因此只有实际可用的功能,而不是视图/端点/路由的名称。
【解决方案2】:

试试app.view_functions

def check_cache(view_function, **kwargs):
    flipped_view_functions_dict = dict((v, k) for k, v in app.view_functions.iteritems())
    view_name = flipped_view_functions_dict[view_function]
    url = url_for(view_name, **kwargs)
    ... use URL to check cache ...

【讨论】:

  • 这是正确的解决方案。我的下一个问题是在Flask-Cache 内部,在路由装饰器和缓存装饰器之间存在装饰器的情况下,给定的视图函数不一定会引用存储在app.view_functions 中的相同函数。
猜你喜欢
  • 2012-12-11
  • 2021-08-04
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
相关资源
最近更新 更多