2

I'm still working on my project and now it comes to searching the data. Usually I do a post request do a route, giving the search string as parameter:

@bp.route('/search', methods=['GET', 'POST'])
def search():
    if request.method == 'POST':
        resp = db.session.query(MyTable).filter(MyTable.name.like('%'+request.form['search_name']+'%')).all()
        ... # do something else

My problem is how to implement pagination when the search results exceed the maximum amount of items per page.

Pagination itself won't be the problem when displaying data without any user action, there are several ways to do that either with Flask-paginate or via Flask-SQLAlchemy's paginate() function. But how to transfer the search string through the other pages since page is given as GET parameter with ?page=x and the search string is a POST parameter?

I somehow ran out of mind and did a lot of investigations on the net, but I only got results on doing pagination on normal data, not search results.

Could somehow give me an advice?

Many thanks in advance, regards, Thomas

brillenheini
  • 793
  • 7
  • 22
  • Why can't you put `page` in POST parameter as well? – Adrian Krupa Jul 02 '19 at 08:46
  • Well, this would mean that I have to wrap a form around the pagination and send every step as POST request including the search string as hidden field to the route. But maybe a session could help me with this problem. Just reading some documents again. – brillenheini Jul 02 '19 at 09:16

1 Answers1

4

I think I've got an solution for this - Flask's session class:

@app.route('/search', methods=['GET', 'POST'])
def search():
    if 'name' in session['search']:
        name = session['search']['name']
    elif request.method == 'POST':
         jboss_name = request.form.get('name')
         session['search']['name'] = name

    page = request.args.get('page', 1, type=int)

    resp = db.session.query(MyTable)\
            .filter(MyTable.name.like('%' + name + '%'))\
            .paginate(page, app.config['ITEMS_PER_PAGE'], False)

    next_url = url_for('search', page=resp.next_num) \
        if resp.has_next else None
    prev_url = url_for('search', page=resp.prev_num) \
        if resp.has_prev else None

    return render_template('search.html',
                            resp=resp,
                            next_url=next_url,
                            prev_url=prev_url)

The first call is done via POST request, sending the data to the corresponding app.route. If the session value is not set yet, it will be set at line 5. Through the session you can ensure that the original search string is taken through all pages.

This may not be highly developed but at least a working example on how to paginate through search results. Not implemented in this short snippet is clearing the session.

Regards, Thomas

brillenheini
  • 793
  • 7
  • 22