1.11 ページング機能(DJango 2.2.7) [Django]
ひとりごと
Webサイトにはほぼ検索機能がありそこには必ずと言っていいほどある
ページング機能
ちょっとその前に、Get と Post について
今まで、セキュリティ観点で Get = ×, Post = 〇という考えでいました。
今回のページング機能は、Getを使っています。最初はPostじゃなきゃ
ダメなんじゃないかと考えていたのですが、
よくよく考えると、Linkタグ(href a) も Getなんですよね。
ログインやデータ登録時のFormタグでは、かならず Post にとして、
ページング時の内容に関してパスワードや個人情報が入っていないのであれば、Getでも良いと
自分の中では整理しました。
まあ、金融系等のセキリティに厳しいシステムでは許されないでしょうが。
(参考サイト)
https://www.ipa.go.jp/security/awareness/vendor/programmingv1/a01_04.html
https://qiita.com/kanataxa/items/522efb74421255f0e0a1
▼2020/02/08 追記
余談ですが、Postして Redirect してGetするパターンを
PRGパターンというそうです。
二重登録防止(予防?)的な考え。
ただ、PRGパターンは賛否両論のようで使うべきでないという方もおる。
https://eiry.bitbucket.io/tutorials/tutorial/models.html#id17
https://tech.nikkeibp.co.jp/it/article/COLUMN/20071112/286994/
https://blog.ohgaki.net/prga_a_ia_fa_sa_pa_bac_ai_eb
▲2020/02/08 追記
ここからページング機能について
では、ひとりごとも終わったのでタイトルの内容について書きたいと思います。
もう下記参考サイトそのままって感じです。
(参考サイト)
https://narito.ninja/blog/detail/89/
https://thinkami.hatenablog.com/entry/2016/03/17/003140
カスタムテンプレートタグ
Djangoの、カスタムテンプレートタグという機能を使います。
Javaで例えるならばTaglibですかね。
アプリケーションフォルダ直下にtemplatetagsディレクトリを作成してそこに保存します。
内容の説明はこちらのサイトを参照して下さい。(まるパクリですので)
(参考サイト)
https://thinkami.hatenablog.com/entry/2016/03/17/003140
テンプレートファイル
内容の説明はこちらのサイトを参照して下さい(まるパクリですので)
(参考サイト)
https://narito.ninja/blog/detail/89/
ビュークラス
ページング用のデータを取得する関数もまるパクリです。
(参考サイト)
https://narito.ninja/blog/detail/89/
上の関数を呼び出すindex処理は、少しだけ独自です。
ページング時に、GETパラメータ内に検索条件有無を確認し、
検索条件があるのならWhere句を生成し、DBデータを取得して
paginate_querysetを呼出します。
Webサイトにはほぼ検索機能がありそこには必ずと言っていいほどある
ページング機能
ちょっとその前に、Get と Post について
今まで、セキュリティ観点で Get = ×, Post = 〇という考えでいました。
今回のページング機能は、Getを使っています。最初はPostじゃなきゃ
ダメなんじゃないかと考えていたのですが、
よくよく考えると、Linkタグ(href a) も Getなんですよね。
ログインやデータ登録時のFormタグでは、かならず Post にとして、
ページング時の内容に関してパスワードや個人情報が入っていないのであれば、Getでも良いと
自分の中では整理しました。
まあ、金融系等のセキリティに厳しいシステムでは許されないでしょうが。
(参考サイト)
https://www.ipa.go.jp/security/awareness/vendor/programmingv1/a01_04.html
https://qiita.com/kanataxa/items/522efb74421255f0e0a1
▼2020/02/08 追記
余談ですが、Postして Redirect してGetするパターンを
PRGパターンというそうです。
二重登録防止(予防?)的な考え。
ただ、PRGパターンは賛否両論のようで使うべきでないという方もおる。
https://eiry.bitbucket.io/tutorials/tutorial/models.html#id17
https://tech.nikkeibp.co.jp/it/article/COLUMN/20071112/286994/
https://blog.ohgaki.net/prga_a_ia_fa_sa_pa_bac_ai_eb
▲2020/02/08 追記
ここからページング機能について
では、ひとりごとも終わったのでタイトルの内容について書きたいと思います。
もう下記参考サイトそのままって感じです。
(参考サイト)
https://narito.ninja/blog/detail/89/
https://thinkami.hatenablog.com/entry/2016/03/17/003140
カスタムテンプレートタグ
Djangoの、カスタムテンプレートタグという機能を使います。
Javaで例えるならばTaglibですかね。
アプリケーションフォルダ直下にtemplatetagsディレクトリを作成してそこに保存します。
内容の説明はこちらのサイトを参照して下さい。(まるパクリですので)
(参考サイト)
https://thinkami.hatenablog.com/entry/2016/03/17/003140
テンプレートファイル
内容の説明はこちらのサイトを参照して下さい(まるパクリですので)
(参考サイト)
https://narito.ninja/blog/detail/89/
ビュークラス
ページング用のデータを取得する関数もまるパクリです。
(参考サイト)
https://narito.ninja/blog/detail/89/
上の関数を呼び出すindex処理は、少しだけ独自です。
ページング時に、GETパラメータ内に検索条件有無を確認し、
検索条件があるのならWhere句を生成し、DBデータを取得して
paginate_querysetを呼出します。
def index(request): log.info('index start') forms = SearchFormSet(request.GET or None) """ GETパラメータのキー内容について。 ページング処理のパラメータは、 'page' 検索絞込み条件の'm_work_history','m_appl_route'の 情報キーが存在した場合は、is_valid実施後にSQLのWhere句を生成する。 """ whereSql = '' # # パラメータに検索条件があるかチェックする # Request.GETからパラメータをリストに保存(lists) # タプルの中にタプルが格納されているので二重ループで、キー名の文字列が含まれているパラメータキーが存在するか # チェックし存在したらフラグをTrueに設定する。 # 1つあったらそれで十分なのでループを抜ける lists = request.GET.lists() is_m_appl_route_key = False #検索条件パラメータ存在有無フラグ is_m_work_history_key = False #検索条件パラメータ存在有無フラグ for tupls in lists: for key in tupls: if 'm_work_history' in key: is_m_work_history_key = True break elif 'm_appl_route' in key: is_m_appl_route_key = True break #どちらかのフラグがTrueとなったら終わり if is_m_appl_route_key or is_m_appl_route_key: break # # 1. パラメータに検索条件があったらSQL文のWHERE句を生成する。 # 2. 検索パラメータが正常に作成されていない場合は下記エラーとなるため、新規にFormを生成する。 # 「マネージメントフォームのデータが見つからないか、改竄されています。」 # これは検索条件なしでページ遷移パラメータが存在している場合に発生する。 # if is_m_work_history_key or is_m_appl_route_key: if forms.is_valid() == True: for form in forms: if form.cleaned_data.get('m_appl_route'): #print( 'm_appl_route=' + str(type(form.cleaned_data.get('m_appl_route')))) whereSql = ' WHERE M_Appl_Route.key_appl_route =\'' + str(form.cleaned_data.get('m_appl_route').key_appl_route) + '\' ' if form.cleaned_data.get('m_work_history'): if whereSql: whereSql = whereSql + ' AND ' else: whereSql = ' WHERE ' whereSql = whereSql + 'M_Work_History.key_history_kbn=\'' + str(form.cleaned_data.get('m_work_history').key_history_kbn) + '\'' #print( 'WHERE=[' + whereSql + ']' ) else: #ありえないけと念のため forms = SearchFormSet(None) else: forms = SearchFormSet(None) # # SQL文作ったり・・ロジック省略 # # cursor = connection.cursor() cursor.execute(sSql) rows = cursor.fetchall() page_obj = paginate_queryset( request, rows, 30 ) #print( '-------------------------------------------------------------------' ) #print( forms ) context = { 'forms' : forms, 'list' : page_obj.object_list, 'page_obj' : page_obj, } #print( context ); return render(request, 'applicantctl/index.html', context)
- ショップ: 楽天ブックス
- 価格: 3,740 円