django Paginator 讓分頁變得完美


參考大佬地址:https://www.zmrenwu.com/courses/django-blog-tutorial/materials/21/

 

類視圖

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import ListView
from base.models import Project, Sign, Environment, Interface, Case, Plan, Report

@method_decorator(login_required, name='dispatch')  # 類裝飾器,需要用 method_decorator 包一下,並指定 類方法
class ReportPage(ListView): # 繼承ListView
    model = Report # 執行要查詢的表名
    template_name = 'base/report_page/report_page.html' # 指定模板
    context_object_name = 'object_list' # 指定模板中使用的數據變量名稱
    paginate_by = 10 # 一頁多少條數據

    def dispatch(self, *args, **kwargs): # 重寫dispatch 函數,供 method_decorator 指向這個函數
        return super(ReportPage, self).dispatch(*args, **kwargs)

    def get_queryset(self): # 重寫查詢,添加查詢的條件等...
        self.plan_id = self.request.GET.dict().get('plan_id', '')
        if self.plan_id:
            return Report.objects.filter(plan_id=self.plan_id).order_by('-report_id') # 倒序返回
        else:
            return Report.objects.all().order_by('-report_id')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({'plan_id': self.plan_id}) # 在返回的字典中可以添加數據
        paginator = context.get('paginator')
        page = context.get('page_obj')
        is_paginated = context.get('is_paginated')
        data = pagination_data(paginator, page, is_paginated) # 接收處理好的分頁數據
        context.update(data)
        return context

 

pagination_data()函數 直接用的大佬的,沒有做修改
def pagination_data(paginator, page, is_paginated):
    if not is_paginated:
        # 如果沒有分頁,則無需顯示分頁導航條,不用任何分頁導航條的數據,因此返回一個空的字典
        return {}

    # 當前頁左邊連續的頁碼號,初始值為空
    left = []

    # 當前頁右邊連續的頁碼號,初始值為空
    right = []

    # 標示第 1 頁頁碼后是否需要顯示省略號
    left_has_more = False

    # 標示最后一頁頁碼前是否需要顯示省略號
    right_has_more = False

    # 標示是否需要顯示第 1 頁的頁碼號。
    # 因為如果當前頁左邊的連續頁碼號中已經含有第 1 頁的頁碼號,此時就無需再顯示第 1 頁的頁碼號,
    # 其它情況下第一頁的頁碼是始終需要顯示的。
    # 初始值為 False
    first = False

    # 標示是否需要顯示最后一頁的頁碼號。
    # 需要此指示變量的理由和上面相同。
    last = False

    # 獲得用戶當前請求的頁碼號
    page_number = page.number

    # 獲得分頁后的總頁數
    total_pages = paginator.num_pages

    # 獲得整個分頁頁碼列表,比如分了四頁,那么就是 [1, 2, 3, 4]
    page_range = paginator.page_range

    if page_number == 1:
        # 如果用戶請求的是第一頁的數據,那么當前頁左邊的不需要數據,因此 left=[](已默認為空)。
        # 此時只要獲取當前頁右邊的連續頁碼號,
        # 比如分頁頁碼列表是 [1, 2, 3, 4],那么獲取的就是 right = [2, 3]。
        # 注意這里只獲取了當前頁碼后連續兩個頁碼,你可以更改這個數字以獲取更多頁碼。
        right = page_range[page_number:page_number + 2]

        # 如果最右邊的頁碼號比最后一頁的頁碼號減去 1 還要小,
        # 說明最右邊的頁碼號和最后一頁的頁碼號之間還有其它頁碼,因此需要顯示省略號,通過 right_has_more 來指示。
        if right[-1] < total_pages - 1:
            right_has_more = True

        # 如果最右邊的頁碼號比最后一頁的頁碼號小,說明當前頁右邊的連續頁碼號中不包含最后一頁的頁碼
        # 所以需要顯示最后一頁的頁碼號,通過 last 來指示
        if right[-1] < total_pages:
            last = True

    elif page_number == total_pages:
        # 如果用戶請求的是最后一頁的數據,那么當前頁右邊就不需要數據,因此 right=[](已默認為空),
        # 此時只要獲取當前頁左邊的連續頁碼號。
        # 比如分頁頁碼列表是 [1, 2, 3, 4],那么獲取的就是 left = [2, 3]
        # 這里只獲取了當前頁碼后連續兩個頁碼,你可以更改這個數字以獲取更多頁碼。
        left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]

        # 如果最左邊的頁碼號比第 2 頁頁碼號還大,
        # 說明最左邊的頁碼號和第 1 頁的頁碼號之間還有其它頁碼,因此需要顯示省略號,通過 left_has_more 來指示。
        if left[0] > 2:
            left_has_more = True

        # 如果最左邊的頁碼號比第 1 頁的頁碼號大,說明當前頁左邊的連續頁碼號中不包含第一頁的頁碼,
        # 所以需要顯示第一頁的頁碼號,通過 first 來指示
        if left[0] > 1:
            first = True
    else:
        # 用戶請求的既不是最后一頁,也不是第 1 頁,則需要獲取當前頁左右兩邊的連續頁碼號,
        # 這里只獲取了當前頁碼前后連續兩個頁碼,你可以更改這個數字以獲取更多頁碼。
        left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]
        right = page_range[page_number:page_number + 2]

        # 是否需要顯示最后一頁和最后一頁前的省略號
        if right[-1] < total_pages - 1:
            right_has_more = True
        if right[-1] < total_pages:
            last = True

        # 是否需要顯示第 1 頁和第 1 頁后的省略號
        if left[0] > 2:
            left_has_more = True
        if left[0] > 1:
            first = True

    data = {
        'left': left,
        'right': right,
        'left_has_more': left_has_more,
        'right_has_more': right_has_more,
        'first': first,
        'last': last,
    }

    return data

 

html模板

{% if is_paginated %}
                    <ul class="pagination">
                        {% if first %}
                            <li class="page"><a href="?plan_id={{ plan_id }}&page=1">1</a></li>
                        {% endif %}
                        {% if left %}
                            {% if left_has_more %}
                                <li class="page"><a href="javascript:void(0)">...</a></li>
                            {% endif %}
                            {% for i in left %}
                                <li class="page"><a href="?plan_id={{ plan_id }}&page={{ i }}">{{ i }}</a></li>
                            {% endfor %}
                        {% endif %}
                        <li class="page"><a href="javascript:void(0)" class="active"> {{ page_obj.number }}</a></li>
                        {% if right %}
                            {% for i in right %}
                                <li class="page"><a href="?plan_id={{ plan_id }}&page={{ i }}">{{ i }}</a></li>
                            {% endfor %}
                            {% if right_has_more %}
                                <li class="page"><a href="javascript:void(0)">...</a></li>
                            {% endif %}
                        {% endif %}
                        {% if last %}
                            <li class="page"><a
                                    href="?plan_id={{ plan_id }}&page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a>
                            </li>
                        {% endif %}

                    </ul>
                {% endif %}

 

分頁完成示例:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM