概要
flaskで作成した検索のWEBアプリを、flask-paginateでページネーション(ページ割り)しました。
ページ遷移で少し詰まったので、記事にします。
環境
- flask 1.1.2
- flask-paginate 0.7.1
初回作成(不具合あり)
~/resultページから検索条件をPOSTでrequest.formとして取得し、検索した結果がresults(リスト)として得られる状態です。
from flask import Flask, request, redirect, url_for, render_template, flash, session
from flask_paginate import Pagination, get_page_parameter
app = Flask(__name__)
@app.route('/result', methods=['GET', 'POST'])
def show_results():
# request.formを用いた、なんらかの検索
results = [...] # 検索結果(リスト)
page = request.args.get(get_page_parameter(), type=int, default=1)
per_page = 1
res = results[(page-1)*per_page: page*per_page]
pagination = Pagination(page=page, total=len(results), per_page=per_page, css_framework='bootstrap4')
return render_template('index.html', books=res, request_form=request.form, pagination=pagination)
if __name__ == '__main__':
app.run(debug=True)
上記コードにより、次のようなページネーションが表示されます。
resultsが検索結果の場合、数字の2,3をクリックしてページ遷移すると、正しい結果が表示されません。
検索条件を保存していないので、ページ遷移すると検索条件なしで再検索が行われてしまいます。
(flask-paginateのページ遷移はGETなので、検索条件を取得できません。)
改良(セッションを利用)
検索条件を保存するため、検索の前に以下の処理を入れました。
- POSTの場合のみ、request.formをsessionに保存する。
- POSTでもGETでも、sessionからrequest.formを割り当てる。session.get('request_form')がなかった場合はNoneが返る。
from flask import Flask, request, redirect, url_for, render_template, flash, session
from flask_paginate import Pagination, get_page_parameter
app = Flask(__name__)
app.secret_key = b'XXXXXXXXX' # 追加 sessionを利用するために必要
@app.route('/result', methods=['GET', 'POST'])
def show_results():
if request.method == 'POST': # 追加
session['request_form'] = request.form # 追加
request.form = session.get('request_form') # 追加
# request.formを用いた、なんらかの検索
results = [...] # 検索結果(リスト)
page = request.args.get(get_page_parameter(), type=int, default=1)
per_page = 1
res = results[(page-1)*per_page: page*per_page]
pagination = Pagination(page=page, total=len(results), per_page=per_page, css_framework='bootstrap4')
return render_template('index.html', books=res, request_form=request.form, pagination=pagination)
if __name__ == '__main__':
app.run(debug=True)
これで、ページ遷移すると、sessionに保存された検索条件で検索が行われるので、正しい結果が表示されます。
参考
Flask Paginate(公式)
FlaskのページネーションはFlask-paginateを使うと簡単に実装できる
検索結果のページネーションについて(stack overflow) :Djangoの例