Yaji_S’s diary

プログラミング学習のアウトプットブログ

【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">&laquo;</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">&raquo;</span>
                </a>
            </li>
        {% endif %}
    </ul>
</div>

実装の結果の様子は以下の写真のようになります。
f:id:Yaji_S:20210123231724p:plain

テンプレートについては他にも種類があるそうなので、
好きなデザインのページネーションを導入ができそうです。