元工場員からプログラマーなれた人の日記

学んだ知識をあべのさんなりにアウトプットしていきます。

【5分でわかる】Djangoのページネーションの使い方

f:id:abenosan:20181011125111j:plain Web開発では欠かせないページネーションについて、軽くまとめてみたいと思います。

ページネーションって?

ページネーションとは、誰もが一度は使ったことがあると思います。
そう、ネットサーフィンをしていたらよく見かけるあれです。
f:id:abenosan:20181011103916p:plain
普段、当たり前のように使っているかと思いますが、実は裏方で「1ページに何個のレコードを表示する」と設定されているんです。

Googleだと膨大な数のWebページがあるので、1度にそれを表示すると・・・
想像つきますよね・・・

なので、ページネーションという機能を使って表示件数を制限するわけです。 f:id:abenosan:20181011122147p:plain
それでは実際に使ってみよう!

簡単な流れ

  1. viewsに表示させる内容を書く
  2. urlsに表示先を書く
  3. テンプレートに表示

Paginatorクラスの使い方

Djangoには元からページネーションするクラスが入っています!
それが「Paginator」クラスです。便利ですね!
このクラスを使うことで、簡単にページを分けてレコードを取り出すことができます。

インスタンス作成

変数 = Paginator( コレクション , レコード数)

第一引数:レコード全体をまとめたコレクション
(allやfilterメソッドで得られるオブジェクト)
第二引数:1ページあたりのレコード数

使用例

page = Paginator(data,5)

これで、dataオブジェクトの5つのレコードを変数pageに格納しています。
簡単ですね!

viewsに記入しよう

それでは、Paginatorインスタンスの作り方を理解したので実際にviews.pyに記入していきましょう。
ここでは簡単なページを作成しています。

from django.core.paginator import Paginator

def index(request,num=1):
    data = hoge.object.all()    # hoge=表示したいテーブル名
    page = Paginator(data , 5)
    params = {
    'data':page.get_page(num)
  }
    render(request,'表示先',params)

なんだこれは・・・と思うかもしれませんが、やってることは非常にシンプルです。
それでは一行ずつ見ていきましょう。

from django.core.paginator import Paginator
Paginatorクラスを利用できるようにインポートしています。 これを忘れるとPaginatorクラスが動かないので忘れないでくださいね!

data = hoge.object.all()
元となるデータをすべてdataに格納しています。

page = Paginator(data , 5)
先ほど作った変数(data)を使って、Paginatorの第一引数に格納しています。
これでpageにはhogeの中にある5つのデータが入っています。

'data':page.get_page(num) [Paginator],get_page(番号)
引数にページ番号を指定すれば、そのページのレコードを取り出すことができます。

これで、viewsは完成しました。

urlsの追加

ページごとに表示を変更しないといけないのでurlsにページ番号をアクセスできるようにしましょう。

pah('<int:num>',views.index,name='index'),

Templateを記入しよう

先ほど作った関数を表示させるためには、Templateが必要ですよね。
HTMLを書いていきましょう。

{% load static %}
<!doctype html>
<html lang='ja'>
    <head>
        <meta charset='utf-8'>
        <title>hello</title>
        <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}" />
    </head>
    <body>
        <table>
            <tr>
                <th>name</th>
            </tr>
        {% for item in data %}
            <tr>
                <td>{{item.user_id}}</td>
            </tr>
        {% endfor %}
        </table>
        <div class="pagination">
            {% if data.has_previous %}
                <a href="{% url 'index' %}">&laquo;first</a>
                <a href="{% url 'index' %}{{ data.previous_page_number }}">&laquo;prev</a>
            {% endif %}
            <span>
                [{{ data.number }}/{{ data.paginator.num_pages}}]
            </span>
            {% if data.has_next %}
                <a href="{% url 'index' %}{{ data.next_page_number}}">next&raquo;</a>
                <a href="{% url 'index' %}{{ data.paginator.num_pages }}">last&raquo;</a>
            {% endif %}
        </div>
        <p><a href="{% url goto %}">{{ goto }}</a></p>
        <p><a href="{% url add %}">{{ add }}</a></p>
    </body>
</html>

一度、アクセスしてみてください。
表示はGoogleとは異なりますがやっていることは同じです。
f:id:abenosan:20181011123338p:plain
どうですか?思ったより簡単でしょ。
これでページネーションの完成です。

ページ移動リンクの仕組み

前のページに移動

前のページに移動するリンクは「first」と「prev」を用意しています。

{% if data.has_previous %}
    // ここにリンクを用意
{% endif %}

ここではdataの「hax_previous」メソッドを呼び出しています。
これは、前のページがあるかどうがチェックするメソッドです。
Trueであれば、first と prev のリンクを表示しています。

現在のページ

[{{ data.number }}/{{ data.paginator.num_pages}}]
現在のページは dataの「number」で得ることができます。
また、レコードが全部で何ページ分あるがどうかの確認は「data.paginator」の「num_pages」で取得できます。

終わりに

どうでしょうか?簡単にまとめすぎたかもしれませんが、大まかな動きは理解できたのではないでしょうか。
実際にWebアプリケーションを作成するのであれば、ページネーションは必ずお世話になるので、是非使い方を習得してください。