Djangoでのページネーション機能の実装

ページネーション機能のコード

ページネーションのロジックとスタイル

from django.utils.safestring import mark_safe
from django.http.request import QueryDict

class PageNavigator:
    """
    必要なパラメータ
    page: 現在のページ番号 (必須)
    total_items: 全データ数 (オプション)
    items_per_page: 1ページあたりの表示アイテム数 (オプション)
    max_pages: 最大表示ページ数 (オプション)
    """

    def __init__(self, page, total_items, items_per_page=10, max_pages=11):
        try:
            self.page = int(page)
            if self.page <= 0:
                self.page = 1
        except Exception:
            self.page = 1

        # 全データ数
        total_items = total_items
        # 1ページあたりの表示アイテム数
        items_per_page = items_per_page

        # 全ページ数
        total_pages, remainder = divmod(total_items, items_per_page)
        if remainder:
            total_pages += 1
        # 最大表示ページ数
        half_max_pages = max_pages // 2

        if total_pages <= max_pages:
            page_start = 1
            page_end = total_pages
        else:
            if self.page - half_max_pages <= 0:
                page_start = 1
                page_end = max_pages
            elif self.page + half_max_pages > total_pages:
                page_end = total_pages
                page_start = total_pages - max_pages + 1
            else:
                page_start = self.page - half_max_pages
                page_end = self.page + half_max_pages

        self.page_start = page_start
        self.page_end = page_end
        self.total_pages = total_pages
        self.start_index = (self.page - 1) * items_per_page
        self.end_index = self.page * items_per_page

    @property
    def page_links(self):
        links = []

        if self.page == 1:
            links.append('<li class="disabled"><a aria-label="Previous"> <span aria-hidden="true">&laquo;</span></a></li>')
        else:
            links.append('<li><a href="?page={}" aria-label="Previous"> <span aria-hidden="true">&laquo;</span></a></li>'.format(self.page - 1))

        for i in range(self.page_start, self.page_end + 1):
            if i == self.page:
                links.append('<li class="active"><a href="?page={}">{}</a></li>'.format(i, i))
            else:
                links.append('<li><a href="?page={}">{}</a></li>'.format(i, i))

        if self.page == self.total_pages:
            links.append('<li class="disabled"><a aria-label="Next"> <span aria-hidden="true">&raquo;</span></a></li>')
        else:
            links.append('<li><a href="?page={}" aria-label="Next"> <span aria-hidden="true">&raquo;</span></a></li>'.format(self.page + 1))

        return ''.join(links)

View での使用例

# 顧客リストの表示
class CustomerListView(View):
    def get(self, request, *args, **kwargs):
        query = self.search(["qq", "name", "phone"])
        if request.path_info == reverse('customer_list'):
            title = '共有顧客'
            customers = models.Customer.objects.filter(query, consultant__isnull=True)
        else:
            title = '私の顧客'
            customers = models.Customer.objects.filter(query, consultant=request.user_obj)

        paginator = PageNavigator(request.GET.get('page', 1), customers.count(), 10, 3)
        return render(request, 'consultant/customer_list.html', {
            "customers": customers[paginator.start_index:paginator.end_index],
            "page_links": paginator.page_links,
            "title": title
        })

HTML ページでの Bootstrap スタイルの適用

<script src="bootstrap-3.3.7/css/bootstrap.css"></script>
<nav aria-label="Page navigation">
    <ul class="pagination">
        {{ page_links }}
    </ul>
</nav>

タグ: Django pagination Bootstrap Python HTML

5月25日 12:42 投稿