Reputation: 5932
The cache system I'm using (Flask-Cache) uses URLs to calculate cache keys. From a different place in the code I get passed a view function, and then need to check if the view has been cached.
Firstly, the current iteration of Flask-Cache needs the request to calculate the cache key, but I have made a patch that fixes the deficiency for simple cases, by getting the URL with url_for(view_function.__name__, **kwargs)
.
The problem is that now I've started using Flask Blueprints, and simply using view_function.__name__
in url_for
will not find the blueprint route (raises BuildError).
@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')
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')
How do I get the URL for the route/view function, when it's defined via a Blueprint?
Or alternatively, how do I make cache keys that will work when using blueprints? (And can be calculated via a decorator on a view function, and doesn't clash when two or more blueprints have view functions with the same name)
Upvotes: 1
Views: 4382
Reputation: 433
Blueprints, by default, prepend the endpoint name with the blueprint name. In this way, the url_for string:
url = url_for('user_page')
Becomes:
url = url_for('user_blueprint.user_page')
Now, you are creating your url_for strings with the function name, so you can either switch to explicitly passing the endpoint strings as above, or use:
url = url_for('user_blueprint.' + view_function.__name__)
I don't know of a programmatic way to automatically find the blueprint name from the view_function.
Upvotes: 3
Reputation: 15100
Try with 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 ...
Upvotes: 2