Pagination in search results with Python/Flask

Viewed 3800

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

1 Answers

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

Related