DjangoでPaginationを実装する

Djangoのdjango-pure-paginationを使ってpaginationを試してみます。

###1.環境

OS Windows 10 Home 64bit
Python 3.6.5
Django 2.0.7

###2.インストール

pipでインストールします。

```cmd.prompt
(venv) C:\data\python>pip install django-pure-pagination
```

###3.アプリを作成

(1)startappでアプリを作成する。

```cmd.prompt
python manage.py startapp testpagenation2
```

(2)model.pyを編集

なんでもいいですが、Articleにしました。

```testpagenation2\models.py
from django.db import models

class Article(models.Model):
    title = models.CharField('title', max_length=255)
    content = models.CharField('content', max_length=255)
```

(3)settings.py

プロジェクトにアプリを追加します。

```myproject\settings.py
INSTALLED_APPS = [
    ・・・
    'testpagenation2', #追加
]
```

(4)migrate

modelをmigrateします。

```cmd.prompt
python manage.py makemigrations testpagenation2
python manage.py migrate testpagenation2
```

(5)views.py

paginationは「PaginationMixin」を継承して「paginate_by = 10」を追加するだけです。

```py:cmd.prompt
from django.views.generic import ListView
from pure_pagination.mixins import PaginationMixin
from . import models

class IndexView(PaginationMixin, ListView):
    model = models.Article
    template_name = 'testpagenation2/index.html'
    paginate_by = 10
```

(6)urls.py(アプリケーションレベル)

```testpagenation2\urls.py
from django.urls import path
from . import views

app_name="testpagenation2"
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
]
```

(7)templates\testpagenation2\index.html

base.htmlを継承しています。paginationは、他のアプリでも使うことを想定してい外部ファイル化してimportしています。

```html
{% extends "commons/base.html" %}

{% load static %}

{% block title %}
{% endblock title %}

{% block links %}
<link href="{% static 'css/pagination.css' %}" rel="stylesheet">
{% endblock links %}

{% block headertitle %}
django-pure-pagination
{% endblock %}

{% block content %}

<form class="col-md-12">
    <div>
        <table class="table table-borderd table-sm ">
            <tr>
                <th>title</th>
                <th>content</th>
            </tr>
            {% for article in object_list %}
                <tr>
                    <td>{{ article.title }}</td>
                    <td>{{ article.content }}</td>
                </tr>
            {% endfor %}
        </table>
    </div>

    <br/>

    {% include 'commons\pagination2.html' %}
  </form>
{% endblock %}
```

(8)templates\commons\pagination2.html

各ページへのリンクと、現在表示中のページ番号を表示するようにしました。

```templates\commons\pagination2.html
<div class="row mx-auto" style="width: 600px;">
{% if is_paginated %}
  <ul class="pagination">
      {% if page_obj.has_previous %}
        <li><a class="page-link text-primary d-inline-block" href="?{{ page_obj.previous_page_number.querystring }}">前</a></li>
      {% else %}
        <li class="disabled"><div class="page-link text-secondary d-inline-block disabled" href="#">前</div></li>
      {% endif %}

      {% for link_page in page_obj.pages %}
        {% if link_page %}
          {% if link_page == page_obj.number %}
            <li class="disabled"><div class="page-link text-secondary d-inline-block disabled" href="#">{{ link_page }}</div></li>
          {% else %}
            <li><a class="page-link text-primary d-inline-block" href="?{{ link_page.querystring  }}">{{ link_page }}</a></li>
          {% endif %}
        {% else %}
          <li class="disabled"><a class="page-link text-secondary d-inline-block text-muted" href="#">・・・</a></li>
        {% endif %}
      {% endfor %}

      {% if page_obj.has_next %}
        <li><a class="page-link text-primary d-inline-block" href="?{{ page_obj.next_page_number.querystring }}">次</a></li>
      {% else %}
        <li class="disabled"><div class="page-link text-secondary d-inline-block disabled" href="#">次</div></li>
      {% endif %}
      <li class="p-md-2">
        {{ page_obj.paginator.num_pages }} 頁中 {{ page_obj.number }} 頁目を表示
      </li>
  </ul>
{% endif %}
</div>
```
※base.htmlは割愛します。以下を参照ください。
[Python + Djangoで独自のユーザ認証を実装する](https://qiita.com/tiguchi919/items/54424f619829a6d135fc)

(9)urls.py(プロジェクト)

最後にプロジェクトにアプリのURLを追加します。

```myproject\urls.py
urlpatterns = [
    ・・・
    path('testpagenation2/', include('testpagenation2.urls')), #"追加")
    path('admin/', admin.site.urls),
]
```

###4.確認

最後に確認してみます。

```cmd.prompt
(venv) C:\data\python\myproject>manage.py runserver
```

http://localhost:8000/testpagenation2

![image.png](https://qiita-image-store.s3.amazonaws.com/0/246741/3413a676-87ff-f10a-cf36-02b90e6f860c.png)


Djangoではページネーションも簡単。