Djangoで使えるページネーション

## 概要

DjangoはRuby on Railsのpython版のような、非常に強力なフレームワークです。Djangoの使い方に関しては、様々な有志が制作したドキュメントと、公式のドキュメントに丸投げしたいと思います。このドキュメントはDjangoで作ったページにページネーションを作りたい人向けに、bootstrap4とDjangoの組み込みタグを使用した、テンプレートを提供します。よって提供するソースコードを実行するためには、bootstrap4のjavascriptファイルとcssファイルをhtmlに読み込む必要があります。

## ページネーション(pagination)とは

そもそも、ページネーションとは何かというと、ブログの下などにあるページ番号を表すこいつのことです。

![pagination.PNG](https://qiita-image-store.s3.amazonaws.com/0/241757/378c3f33-05be-3816-fb89-9d99fdd58eeb.png)

これにちゃんと名前があったんですねｗ私は知らずに、「ページの下　番号　作り方」など無様な検索ワードで調べてページネーションという名前を知りました。名前がわからないとドキュメントを調べるのも大変ですね。

このページネーションですが、bootstrapにページネーションを作るための便利なクラスが用意されています。しかしこのクラスを利用する場合、どの番号を表示するか、アクティブ（番号に色を付ける）のはどれかを指定しなくてはいけません、この数値の指定はは当然、開いているページ番号によって違うため、htmlに直書きしておくわけにもいきません。

今回はDjangoでページネーションを実装する人向けのテンプレートを提供したいと思います。ソースコードに関しては以下のgithubにまとめて公開をしておくため、その内容について搔い摘んで説明を行いたいと思います。

https://github.com/Uno-Takashi/django_pagination_template

## 解説

まず、最も大切なpaginationのテンプレートファイルです。

``` html:pagination.html
<nav aria-label="Page navigation example">
  <ul class="pagination justify-content-center">
    <li class="page-item"> 
     <a class="page-link" href="?page=1" aria-label="Top">
        <span aria-hidden="true">&laquo;</span>
        <span class="sr-only">Top</span>
      </a>
    </li>
     <li class="page-item">
      <a class="page-link" href="?page={{ page_active|add:"-1" }}" aria-label="Previous">
        <span aria-hidden="true">&lt;</span>
        <span class="sr-only">Previous</span>
      </a>
    </li>
    {% for anc in page%}
    {% if page_active == anc %}
    <li class="page-item active"><a class="page-link" href="?page={{anc}}">{{anc}}<span class="sr-only">(current)</span></a>
      </li>
    {% else%}
    <li class="page-item"><a class="page-link" href="?page={{anc}}">{{anc}}</a></li>
    {% endif %}
     {% endfor %}
    
     <li class="page-item">
      <a class="page-link" href="?page={{ page_active|add:"1" }}" aria-label="Next">
        <span aria-hidden="true">&gt;</span>
        <span class="sr-only">Next</span>
      </a>
    </li>
    <li class="page-item">
      <a class="page-link" href="?page={{page_last}}" aria-label="Last">
        <span aria-hidden="true">&raquo;</span>
        <span class="sr-only">Last</span>
      </a>
    </li>
  </ul>
</nav>
```
このファイルがpaginationの本体です。このファイルを任意のhtmlの組み込みたいところに以下の組み込みタグを挟むことで、そこにページネーションを表示することができます。


```html:
{% include "app/pagination.html" %}
```
またコピペするだけでなく、3つのパラメータの指定が必要です。
- page : 表示するページ数のリスト。例えば2~5ページ目のページネーションを表示したいのなら[2,3,4,5]というリストをviews.pyで渡さなくてはならない。
- page_active : アクティブページの番号。上のように2~5ページ目のページネーションを表示しているとき、開いているページが3であればそれを指定すると、青く表示される。intデータ
- page_last : 最後のページ。intデータ。

このテンプレートのソースコードの中で、Djangoの組み込みタグにかかわる該当部分は以下の部分です。ここは固定の>マークなどを出すところではなく、数値部分を表示するところです。

```html
    {% for anc in page%}
    {% if page_active == anc %}
    <li class="page-item active"><a class="page-link" href="?page={{anc}}">{{anc}}<span class="sr-only">(current)</span></a>
      </li>
    {% else%}
    <li class="page-item"><a class="page-link" href="?page={{anc}}">{{anc}}</a></li>
    {% endif %}
     {% endfor %}

```

pageは先ほど説明した通りリストですので、その要素についてループを回しています。やっていることといえば、activeであれば光らせるための場合分けくらいなものです。今回はリンクは?page=(ページ数)としてあります。例えばhomeでこの3ページ目に行くためのリンクが押された場合home/?page=3という風にパラメータが設定されます。このパラメータの解析などにrequestに入っていますのでurls.pyやviews.pyなどで解析する必要があります。

最後にviews.py内のパラメータの受け渡しのサンプルは以下の通りです。

```python

    return render(
        request,
        'app/index.html',
        {
            'site_name':site_name,
            'title':'Home Page',
            'year':datetime.now().year,
            'page':page_list,
            'page_active':page_active, #intデータ
            'page_last':page_last #intデータ
        }
    )
```

## 最後に

このままのソースコードをそのまま使える可能性は低いでしょうが、少しのチューニングを行えば割と汎用的に扱えると思います。このソースコードのライセンスに関してはgithubに詳細は書いておきますが、コピペは自由ですので、車輪の再開発を防ぐのに少しでも役立てていただければと思います。
また、間違い、修正点などがございましたらご一報くださいませ。(こうしたほうがきれいなども歓迎)
コメント貰うと喜びます。

実行環境
- Django 2.0
- bootstrap4