I am writing a Flask site for which I would like to have routes like this:
@app.route('/')
@app.route('/<page_id>')
@app.route('/<page_id>/<subpage_id>')
def page(page_id=None, subpage_id=None):
...
While it seems like this should work in theory, it looks like this actually breaks static resources located in the root static/ directory. I assume the reason for this is that my dynamic route actually matches 'static/style.css' and thus overrides the normal handler for static files.
Is there any way around this? Is there a 'static' handler I can forward the request to if I detect that page_id=='static'?
Edit: Here is a working sample
@app.route('/<page_id>/<subpage_id>/<subsubpage_id>')
def xxx(page_id=None, subpage_id=None, subsubpage_id=None):
return 'hello'
If you open http://127.0.0.1:5000/static/css/style.css
now you should get a 'hello' instead of the file.
Regarding the root of your problem:
You can register route handlers directly by using
app.add_url_rule
. It will use the function's name forurl_for
by default, yes, but you can override that by passing anendpoint
argument.So maybe you'd have something like this:
Getting the session may or may not be tricky, and may or may not involve work like manually calling
session.remove()
; I haven't tried using SQLAlchemy outside a Flask handler before. Assuming you're using SQLA in the first place.Also see the documentation on route handling.
As for the original question of routes taking priority over static files, I genuinely don't know; based on my reading of the Flask and Werkzeug docs, that shouldn't happen. If you still wish to solve this by manually serving static files, perhaps
send_from_directory
will help. Presumably your web server will serve static files directly in production, anyway, so it might not be worth the metaprogramming gunk above.PS: An afterthought; Pyramid's traversal might be a better fit if your entire site lives in a database. It examines path components one at a time dynamically, rather than having a fixed list of static routes.
This is a horrible hack but you could probably just do something akin to: