[Flask] Confused by an unexpected route-to-function mapping

Gergely Polonkai gergely at polonkai.eu
Mon Feb 7 13:53:09 EST 2022


Hello,

i think the problem is that the URL part you intend to be used as the
filename contains a slash. Unless explicitly told to @route, it doesnʼt
match anything after a slash is found

To avoid this, you should use the path: modifier in the rule:

@app.route('/<int:month>/<int:year>/<path:filename>')

Best,
Gergely

On Mon, 27 Dec 2021, 12:33 Skip Montanaro, <skip.montanaro at gmail.com> wrote:

> I'm returning to Flask after several years away (and never having done
> much of any significance with it before). I'm having trouble with the
> mapping between routes and the functions which handle them.
>
> I have two functions, each of which is meant to handle a number of related
> routes. The first is just supposed to normalize things and do a permanent
> redirect to the second
>
> @app.route('/<int:year>-<int:month>/html/<filename>')
> @app.route('/CR/<int:year>-<int:month>/html/<filename>')
> @app.route('/<int:year>-<int:month>')
> @app.route('/<int:year>-<int:month>/<filename>')
> def old_cr_month(year, month, filename="index.html"):
>     print(">> old_cr_month:", year, month, filename)
>
>     raise Exception
>
>     return redirect(url_for("cr", year=year, month=month,
>                             filename=filename),
>                     code=301)
>
>
> @app.route("/CR")
> @app.route("/CR/")
> @app.route('/CR/<int:year>/<int:month>')
> @app.route('/CR/<int:year>/<int:month>/<filename>')
> def cr(year=None, month=None, filename="index.html"):
>     print(">> cr:", year, month, filename)
>     ...
>
>
> When I visit this URL:
>
> http://super.secret.website/CR/2000-09/html/maillist.html
>
>
> old_cr_month is called, as I expect. Its print function is called and the
> embedded exception is raised.
>
> When I visit this URL:
>
> http://super.secret.website/CR/2000-09/html/threads.html
>
>
> the old_cr_month handler isn't called. Instead, the cr function is
> enlisted to handle the request and its print function is called.
> Strangely, it does seem to get year, month and filename correct. This
> despite none of the defined routes for cr having URL templates with either
> the year-month form or an embedded html directory in the middle.
>
> When I dump the app object in the debugger the displayed url_map looks to
> me like old_cr_month should have handled the URL (my candidate route
> mapping highlighted in red).
>
> Map([<Rule '/hello' (HEAD, OPTIONS, GET) -> hello>,
>  <Rule '/CR/' (HEAD, OPTIONS, GET) -> cr>,
>  <Rule '/CR' (HEAD, OPTIONS, GET) -> cr>,
>  <Rule '/' (HEAD, OPTIONS, GET) -> index>,
>  <Rule '/CR/<year>-<month>/html/<filename>' (HEAD, OPTIONS, GET) ->
> old_cr_month>,
>  <Rule '/<year>-<month>/html/<filename>' (HEAD, OPTIONS, GET) ->
> old_cr_month>,
>  <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
>  <Rule '/CR/<year>/<month>/<msg>' (HEAD, OPTIONS, GET) -> cr_message>,
>  <Rule '/CR/<year>/<month>/<filename>' (HEAD, OPTIONS, GET) -> cr>,
>  <Rule '/CR/<year>/<month>' (HEAD, OPTIONS, GET) -> cr>,
>  <Rule '/<year>-<month>/<filename>' (HEAD, OPTIONS, GET) -> old_cr_month>,
>  <Rule '/<year>-<month>' (HEAD, OPTIONS, GET) -> old_cr_month>])
>
>
> Here's my setup:
>
> $ flask --version
> Python 3.10.1
> Flask 2.0.2
> Werkzeug 2.0.2
>
>
> I'm running in an Ubuntu 20.04 VM.
>
> What am I missing about routes here? How can two so similarly structured
> URLs be mapped to different handler functions? Is there something I can do
> to dig into the URL-to-handler mapping process?
>
> Thx,
>
> Skip Montanaro
>
> _______________________________________________
> Flask mailing list
> Flask at python.org
> https://mail.python.org/mailman/listinfo/flask
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/flask/attachments/20220207/5ec81f66/attachment.html>


More information about the Flask mailing list