【Django】ページネーションの実装について
表示内容が多い場合、内容物を分割して表示するページネーションという方法が一般的に使われると思います。今回はDjangoでのページネーションの導入について書いていきます。
まず汎用ビューを使っている場合は以下のように簡単に実装できるそうです。
例としてはBlogモデルを例にしてます。
view.py
from django.views.generic import ListView from .models import Blog class BlogistView(Listview): model = Blog paginate_by = 5 (内容物の表示数。今回は5件/1ページ)
汎用ビューを使わない場合は以下の関数で実装すできます。
例としては自分で投稿したブログ内容の一覧を想定しています。
view.py
~ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger ~ ~ class MyPageView( UserPassesTestMixin, LoginRequiredMixin): def paginate_queryset(request, queryset, count): paginator = Paginator(queryset, count) page = request.GET.get('page') try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) return page_obj def myblog_list(request): user = request.user blogs = Blog.objects.filter(custom_user_id=user.id).order_by('post_date') page_obj = paginate_queryset(request, blogs, 5) #(blogs(DBから取得した内容物)を5件/1ページ表示する設定) context = { 'user': user, 'blog_page': page_obj.object_list, 'page_obj': page_obj, } return render(request, 'myblog.html', context)
テンプレートとしては以下の内容で実装しております。
〜〜 <div class="pagenation">ページ</div> <ul class="pagination"> {% if page_obj.has_previous %} <li class="page-item"> <a class="page-link" href="?page={{ page_obj.previous_page_number }}"> <span aria-hidden="true">«</span> </a> </li> {% endif %} {% for num in page_obj.paginator.page_range %} {% if page_obj.number == num %} <li class="page-item active"><a class="page-link" href="#!">{{ num }}</a></li> {% else %} <li class="page-item"><a class="page-link" href="?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if page_obj.has_next %} <li class="page-item"> <a class="page-link" href="?page={{ page_obj.next_page_number }}"> <span aria-hidden="true">»</span> </a> </li> {% endif %} </ul> </div>
実装の結果の様子は以下の写真のようになります。
テンプレートについては他にも種類があるそうなので、
好きなデザインのページネーションを導入ができそうです。