Flask: `@app.route('route')` not relative to root url

Created on 3 Mar 2020  路  4Comments  路  Source: pallets/flask

I thought that the route argument in @app.route is always relative to the root url. However I found myself in a situation where it isn't and is giving me 404 errors.

I have a search function in my website with a view function like this:
@app.route('/search')
@app.route('/search.html')
def searchPosts():

and I'm using flask_whooshalchemyplus for searching. Whenever I search something and I'm at a page like this: host:port/onePage all is good, as I'm redirected to host:post/search?searchQuery=whatever to display the search results.

However, if I am currently at a "deeper" url page, like so: host:port/onePage/secondPage then I'm getting 404, since I'm instead redirected to host:post/onePage/search?searchQuery=whatever

Why is this? Shouldn't the route always be as in the first case? Why would I be redirected to the second case, if the route was absolute?
This whooshsqlalchemyplus hasn't been the only case. I have seen this behavior once more, but I can't recall what was it that lead to it exactly.

Am I missing something?

PS. Sorry for the empty post, I must have accidentally pressed enter.

Most helpful comment

Does changing the action parameter of the HTML form from "search" to "/search" help? When on the page /onePage the first will post to /onePage/search while the second to /search.

All 4 comments

When using url_for, URLs are correctly generated, so it sounds like a bug in your code (which you didn't post)..

Ok, I thought we could deduce a workaround. I will post the code.

I don't use a url_for to create this request, I use the name attribute of an input tag that is used when I submit:

<form class="form-inline" align="center" method="GET" action="search">
    <input type="text" id="searchQuery" name="searchQuery" class="form-control" placeholder="Search this domain.." />
    <button type="submit" id="searchSubmitButton" class="btn btn-primary" style="margin-right: 20px">Search!</button>
</form>

This is in my layout.html.

Then my view function, in routes.py, which intercepts the request:

@app.route('/search')
@app.route('/search.html')
def searchPosts():
    posts = Post.query.whoosh_search(request.args.get('searchQuery'), or_=True, like=True).all()

    return render_template('search_results.html', posts=posts, title = "Search results")

Would any configuration variables matter here? Here's what I have that may affect:

APPLICATION_ROOT = '/'  # url root
SERVER_NAME = '127.0.0.1:5000'
DB_SERVER = 'localhost'

and
app.run(debug=True, use_reloader=False)

Does changing the action parameter of the HTML form from "search" to "/search" help? When on the page /onePage the first will post to /onePage/search while the second to /search.

@zack256 Thank you so much zack! That was it! What a careless mistake. Thanks again!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chuanconggao picture chuanconggao  路  4Comments

sungjinp11 picture sungjinp11  路  3Comments

lnielsen picture lnielsen  路  3Comments

greyli picture greyli  路  3Comments

rkomorn picture rkomorn  路  3Comments