ページネーションの作り方を分かりやすく解説【原則をおさえるのがポイント】

djangoは多くのデータを扱いますので、ページネーションを作りたいという場合もあるかもしれません。

そこで今回は、ページネーションを作る方法を解説していきます。
ページネーションを作るにはPaginatorクラスとPageクラスを使います

djangoには、ページネーションを簡単に作ることができるように、PaginatorというクラスとPageというクラスがあらかじめ備えられています。

ですので、ここからはこれら2つを使って、どうやってページネーションを作るのかをお伝えしていきます。
Paginatorの使い方

Paginatorの作り方はコードをみていった方がイメージがわきやすいと思いますので、コードを見ていきましょう。

ベースコード(List,Detail)を使います。
まずはpaginatorオブジェクトを作る

まずはpaginatorオブジェクトを作ります。

これは、Pagenatorクラスから作られるオブジェクトです。

AppModelにデータが10個入っていると仮定しましょう。

items = AppModel.objects.all()paginator = Paginator(itmes, 3)

これでpaginaorオブジェクトができました。

今回は、10という引数を使ってpaginatorオブジェクトを作りました。

これは、ページネーションのページ区切りを10記事毎にするという意味です。

つまり、今回はデータが10個ありますので、4ページからなるページネーションを作ったということになります。
paginatorオブジェクトから、pagesオブジェクトを作る

次に、paginatorオブジェクトからpagesオブジェクトを作っていきます。

このpagesオブジェクトの中に、ページネーションオブジェクトを作る上で必要な情報が入っています。

pagesオブジェクトを作るには、paginatorオブジェクトのpageメソッドを使います。

pages = paginator.page(1)

pageメソッドは最終的には、return Page(..)と、Pageクラスのオブジェクトを返すようになっていますので、pages = paginator.page()とすることでPageクラスから成るpagesオブジェクトを作ることができるのです。
コードの整理

ここまで書いてきたコードを改めて整理していきましょう。


[コード]

class appfunction(request):   
         items = AppModel.objects.all()   
         paginator = Paginator(items, 3)   
         pages = paginator.page(1)   
         return render(request, 'list.html', {'pages':pages})

このようなコードになります。

pagesオブジェクトでできること

ここから、pagesオブジェクトでできることを紹介していきます。ここを見ると、具体的なページネーションのイメージがわいてくると思います。

前提条件:データの数は10個、3個ずつ区切ったページネーションを作成、pagesオブジェクトの引数は1(1ページ目に関するデータ)


入力 出力 説明
pages <Page 1 of 4>  全ページ現在のページ
pages.has_next()  True  次のページがあるか
pages.has_previous()  False 前のページがあるか
pages.has_other_pages()  True 他のページがあるか
pages.next_page_number()  2 次のページの番号
pages.previous_page_number()  エラー 前のページの番号
pages.start_index  1 ページの先頭の記事番号
pages.end_index  3 ページの最後の記事番号


これらのデータをhtmlファイルに埋め込んでいくことによって、ページネーションを作ることができます。

まずは簡単な表示をさせていきましょう。



[コード]


-list.html
{{ pages.has_next }}
{{ pages.next_page_number }}

 ブラウザではこのような表示になります。

次に、もう少しページネーションらしい形にしていきましょう。
views.pyの調整

今までは、pageは1に指定していましたが、これでは2ページ目をクリックしても、pagesオブジェクトに入るデータは1ページの情報になってしまいます。

ページに応じてpagesオブジェクトに入れるデータを変えるために、views.pyファイルを整えていきましょう。

具体的には、2ページ目をクリックしたら2ページ目の情報がpagesオブジェクトに入り、3ページ目をクリックしたら3ページ目の情報がpagesオブジェクトに入るようにします。



[コード]

class appfunction(request):
    items = AppModel.objects.all()
    paginator = Paginator(items, 3)
    page = request.GET.get('page', 1)
    pages = paginator.page(page)
try:
        pages = paginator.page(page)
    except PageNotAnInteger:
        pages = paginator.page(1)
    except EmptyPage:
        pages = paginator.page(1)
    return render(request, 'list.html', {'pages':pages}) 

request.GET.get('page', 1)で、urlに書かれているpageパラメータの数字を取るようにしています。もしurlにpageパラメータがなければ、1を返すようにしています。

この点があまりよくわからない方は、request.getとrequest.GET.getの違いという記事を参考にしてみてください。

また、try/except文では、pageのパラメーターがinteger型でない場合と、pageのパラメーターがページ数よりも大きい場合、1ページ目を出すように設定しています。

これで、urlで指定したpageパラメーターに応じてpaginationオブジェクトに入れるデータを調整することができるようになりました。
htmlファイルを整える

最後に、htmlファイルを整えていきましょう。


[コード]

{% for item in pages %}
  <tr>
    <td>{{ item.title }}</td>
    <td>{{ item.content }}</td>
  </tr>
{% endfor %}
{% if users.has_other_pages %}
  <ul>
    {% if users.has_previous %}
      <li><a href="?page={{ users.previous_page_number }}">&laquo;</a></li>
    {% else %}
      <li class="disabled"><span>&laquo;</span></li>
    {% endif %}
    {% for i in users.paginator.page_range %}
      <li><a href="?page={{ i }}">{{ i }}</a></li>
    {% endfor %}
    {% if users.has_next %}
      <li><a href="?page={{ users.next_page_number }}">&raquo;</a></li>
    {% else %}
      <li><span>&raquo;</span></li>
    {% endif %}
  </ul>
{% endif %}

これでページネーションの実装ができました。

ポイントは、最初のfor文です。{% for item in pages %}としており、pagesオブジェクトの中に、モデルのデータも入っていることを意識しておくとよいでしょう。
ClassBasedViewで実装

最後に、ClassvBasedViewでページネーションの実装を行っていきましょう。

ClassBasedViewでのページネーションの実装はびっくりするほど簡単です。

view.pyファイルをみていきましょう。


[コード]

class AppView(ListView):   
     model = AppModel   
     context_object_name = 'pages'   
     paginated_by = 10

これだけです。

このように、pagenated_byを設定するだけで、pagesオブジェクトが使えるようになります。

~Django無料講義~のご案内

Code for Djangoが、4時間超の無料Django講義をはじめました
 
・本を出版したCode for Djangoの
 製作者が作ったサイトです。
 
・Code for Djangoの内容も、
 動画で詳しく解説しています。
 
・動画は順次ふやしていきますので、
 ただで学び続けることが可能です。
 
・Djangoの効率的なスキルアップに、
 是非お役立て下さい。
                                                               
                                                                 Django講義はこちら
Created with