LoginSignup
25
24

More than 5 years have passed since last update.

Djangoでページネーションを使う(django.core.paginator)

Posted at

背景

  • 1画面に表示する件数が多かったので、ページネーションを追加する。
  • 標準のdjango.core.paginatorを使う
  • 環境は、Python 3.7.0 + Django 2.1.3

既存のコードの変更

views.pyの変更

  • from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger を追加

  • ページネーション用の関数を追加

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

# ページネーション用に、Pageオブジェクトを返す。
def paginate_query(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 = paginatot.page(paginator.num_pages)
  return page_obj
  • リクエストを受け取る関数の変更
def myapp1(request):
  series = Series.objects.filter(deleted = False).order_by('-created_at')
  page_obj = paginate_query(request, series, settings.PAGE_PER_ITEM)   # ページネーション
  return render(request, 'app1/index.html', {'page_obj': page_obj, 'site_name':settings.SITE_NAME})  # モデルから取得したobjectsの代わりに、page_objを渡す

テンプレートの変更

  • モデルから取得したobjectsの代わりに、page_objを使って表示。
        {% for s in series %}
                <p>{{ s.title }}</p>
        {% endfor %}

を、seriesをpage_objに置き換える(for文の中身はそのままでよい)

        {% for s in page_obj %}
                <p>{{ s.title }}</p>
        {% endfor %}
  • ページネーション部分を追加(別ファイルに作成して、includeするとよい)
<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>

設定ファイルに、1ページに表示する件数を指定

PAGE_PER_ITEM = 15

Bootstrap4を使って見映えをよくする

  • for文用のページ番号のリストを得るために、page_obj.paginator.page_rangeを使う
  • 他は、has_previous, previous_page_number, has_next, next_page_number, numberで指定する
<div>
    <nav aria-label="Page navigation example">
        <ul class="pagination">
            {% if page_obj.has_previous %}
                <li><a class="page-link text-primary d-inline-block" href="?page={{ page_obj.previous_page_number }}"></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.paginator.page_range %}
                {% 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="?page={{ link_page }}">{{ 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={{ page_obj.next_page_number }}"></a></li>
            {% else %}
                <li class="disabled"><div class="page-link text-secondary d-inline-block disabled" href="#"></div></li>
            {% endif %}
        </ul>
    </nav>
</div>
  • このような見映えになります。

スクリーンショット 2018-12-27 15.05.47.png

参考ページ

25
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
24