リストページを作成するとき、1ページに表示する数を20件にして、残りは2ページ目、3ページ目・・・みたいなことをします。これをページネーションといいます。
Django は元々ページネーションの仕組みがあり便利ですが、ページネーション用のパッケージを使うと、さらに便利になります。
私は昔からよく django-pagination を使うのですが、今は他にも良さそうなのが、たくさんあるみたいです。
そこで今回は、いつも使い慣れている django-pagination ではなく、Github で Star がたくさんついている、django-pure-pagination を使ってみたいと思います。
Contents
完成イメージ
バージョン
- Python 3.6.4
- Django 2.0.3
- django-pure-pagination 0.3.0
インストール
Python, Django のインストール
Python と Django のインストールについては、こちらの記事を参考にしてください。
django-pure-pagination のインストール
$ sudo pip install django-pure-pagination Collecting django-pure-pagination Downloading https://files.pythonhosted.org/packages/55/43/50c475f408d3350cec340855970a5ce02ea12f5a53d520315f200b4847a1/django-pure-pagination-0.3.0.tar.gz Installing collected packages: django-pure-pagination Running setup.py install for django-pure-pagination ... done Successfully installed django-pure-pagination-0.3.0
django-pure-pagination の使い方
django-pure-pagination の Github にサンプルプログラムがありますので、それを参考にしたいと思います。
settings.py
ALLOWED_HOSTS = ['*'] INSTALLED_APPS = ( ... 'pure_pagination', 'core' ) TEMPLATES = [ { ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ... } ]
settings.py は startproject で生成し、差分だけを載せています。startproject がわからない場合は、こちらの記事を参考にしてください。
INSTALLED_APPS に先ほどインストールした ‘pure_pagination’ と ページネーションを使う APP ‘core’ を追加します。
外部からのアクセスを許可するために、ALLOWED_HOSTS に ‘*’ を追加しています。
ページネーション結果を表示するテンプレート置き場を、TEMPLETES の DIRS に設定しています。
urls.py
from django.urls import path from core.views import index url patterns = [ path('', index, name='index'), ]
names.py
ページネーションするには、それなりに大量のデータが必要です。DB に自分でテストデータを作っても良いのですが、django-pure-pagination のサンプルプログラムに、5,607 件のアルファベット順のデータがありますので、それを使います。
views.py
from random import randint from django.http import Http404 from django.shortcuts import render_to_response from pure_pagination.paginator import Paginator from core.names import names def index(request): how_many_names = request.GET.get('how_many_names', 60) page_size = request.GET.get('page_size', 10) page_num = request.GET.get('page', 1) try: page_num = int(page_num) page_size = int(page_size) how_many_names = int(how_many_names) except ValueError: raise Http404 selected_names = [] total = len(names) for i in range(how_many_names): selected_names.append(names[randint(0, total - 1)]) p = Paginator(selected_names, page_size, request=request) page = p.page(page_num) return render_to_response('index.html', { 'page': page, })
views.py はサンプルプログラムから拝借しています。
GET パラメータがあれば、その条件で絞り込んでいます。なければ、デフォルトの設定で動きます。
その後、ランダムでページネーション対象データを表示します。
index.html
<!DOCTYPE html> <html> <head> <title>Test page</title> <style type="text/css"> body{ font-family: Arial; font-size: 12px; } .name-box{ padding: 10px; font-size: 12px; border: 1px solid #ddd; border-radius: 5px; } .spacer{ clear:both; height: 10px; } .page, .prev, .next{ display: inline-block; padding: 3px 5px; border: 1px solid #ddd; border-radius: 5px; text-decoration: none; color: #333; background: #eee; font-weight: bold; } .page:hover, .prev:hover, .next:hover{ background: #333; } .page.current{ background: #333; color: white; } .page.disabled, .prev.disabled, .next.disabled{ color: #ddd; cursor: default; } form{ padding: 10px 5px; border: 1px solid #ddd; } form div{ padding: 5px; } form label{ width: 133px; display: inline-block; } form input[type="submit"]{ font-size: 12px; cursor: pointer; } </style> </head> <body> <form action="" method="GET"> <div> <label for="how_many_names">How many names?</label> <input type="text" name="how_many_names" value="60"> </div> <div> <label for="how_many_names">Items per page?</label> <input type="text" name="page_size" value="10"> </div> <input type="submit"> </form><div class="spacer"></div> {% for name in page.object_list %} <div class="name-box"> Name: {{ name }} </div><div class="spacer"></div> {% endfor %} {{ page.render }} </body> </html>
ページネーションを表示するテンプレートです。
tree
$ tree . ├── core │ ├── __init__.py │ ├── apps.py │ ├── names.py │ └── views.py ├── manage.py ├── pagination │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── templates └── index.html 3 directories, 10 files
ファイル構成はこのようになりました。
実行
$ python3.6 manage.py runserver 0.0.0.0:8000
runserver を実行して、ブラウザから http://IPアドレス:8000 にアクセスし、ページネーションの動きが確認できると思います。
まとめ
今回、初めて django-pure-pagination 使ったのですが、なかなか使いやすくて良かったです。
しかし、普段使っている django-pagination は、テンプレートだけで実装できて、かなり強力です。
使いやすさを比べると、django-pagination に軍配があがる気がします。(django-pure-pagination のテンプレートだけ実装方法を私が知らないだけかもしれません。)
もしかしたら、使い込んでいくうちに、django-pagination より django-pure-pagination の方が、良く感じるかもしれないので、もう少し使ってみたいと思います。
Django のページネーションパッケージは、他にもたくさんありますので、自分にあったベストなページネーションを今後も探求していきたいと思います。