0

I have a function in my Flask app that returns the result of a user's search of a database. The user searches from the /search view. When the user searches, I'd like the URL to be example.com/search_results?q={{ q }}&page=1 where q is the search term. Instead, the URL continues to be /search. This is fixed when they navigate through the search results, as the pagination directs them to href="/search_results?q={{ q }}&page={{ page + 1}}"I've tried this a few different ways and I can't figure it out. My routes are:

@app.route('/search', methods=['GET', 'POST'])
def search():
    form = SearchForm()
    search_results=[]
    if form.validate_on_submit():
        search_results = list(db.openings.find({"$text": {"$search": form.search.data}}))
        num_results = len(search_results)
        return render_template('search_results.html', form=form, results=search_results[:10], start=0, end=10, page=1, total=2, q=form.search.data, num_results=num_results)
    return render_template('search.html', form=form)

@app.route('/search_results', methods=['GET', 'POST'])
def search_results():
    form = SearchForm()
    search_results=[]
    if form.validate_on_submit():
        search_results = list(db.openings.find({"$text": {"$search": form.search.data}}))
        num_results = len(search_results)
        return render_template('search_results.html', title='Home', form=form, results=search_results[:10], start=0, end=10, page=1, total=2, q=form.search.data, num_results=num_results)
    per_page = 10
    offset = 0
    page = request.args.get('page', 1, type=int)
    query = request.args.get('q')
    search_results = list(db.openings.find({"$text": {"$search": query}}))
    total = len(search_results)
    t_pages = total // per_page
    start = offset + ((page-1) * per_page)
    end = start + per_page
    results = search_results[start:end]
    num_results = len(search_results)
    return render_template('search_results.html', title='Home', form=form, results=results, page=page, total=t_pages, q=query, start=start, end=end, num_results=num_results)

I've tried creating a new route like @app.route('search_results?q={{ q }}&page=1') and redirecting the search results there, but it hasn't worked. Any suggestions would be appreciated.

7edubs7
  • 15
  • 6
  • What you probably need is to move the actual search logic to the redirect endpoint- the only thing the search endpoint should do is parse the form data and issue the redirect – Paul Becotte Dec 20 '19 at 12:55

1 Answers1

1

In your search() method, after validating the form successfully, return a redirect with code 307 instead of returning a rendered template. See this SO question "Make a POST request while redirecting in flask" for further reading.

Example

from flask import redirect, url_for

# ...

@app.route('/search', methods=['GET', 'POST'])
def search():
    form = SearchForm()

    if form.validate_on_submit():
        return redirect(url_for('search_results'), code=307)

    return render_template('search.html', form=form)


@app.route('/search_results', methods=['GET', 'POST'])
def search_results():
    form = SearchForm()
    #  blah blah
    if form.validate_on_submit():
        #  Form data is avaliable here either posted from browser or 307 redirect

        #  blah blah
pjcunningham
  • 7,676
  • 1
  • 36
  • 49