python django 之 django自帶的分頁

1. 例1: 基礎的分頁
    1). vim app01/views.py
        def users(request):
            from django.core.paginator import Paginator
            curent_page = request.GET.get('p', 1)  # 想獲取的頁數, 沒有指定就返回第一頁
            user_list = District.objects.all()
            paginator = Paginator(user_list, 10)  # 每頁 10 個數據
            """
            參數:
                object_list : 傳入一個對象, 從數據庫中取出的數據對象 ,也就是上面的 user_list
                per_page  : 每頁的頁數
                orphans=0 :
                allow_empty_first_page=True
            """
            # 對象.page(獲取的頁數)  # 獲取指定頁數的數據
            obj = paginator.page(curent_page) # 參數爲 : 要獲取的頁數
            # obj 對象中的方法:
            #      {{ obj.has_next }}               是否有下一頁
            #      {{ obj.next_page_number }}       下一頁頁碼

            #      {{ obj.has_previous }}           是否有上一頁
            #      {{ obj.previous_page_number }}   上一頁頁碼

            #      {{ obj.object_list }}            分頁以後的數據列表
            #      {{ obj.number }}                 當前頁
            #      {{ obj.paginator }}   paginator 對象 就是 paginator = Paginator(list, nmber) 這個方法是爲了調用其下的方法


            return render(request, 'index.html', {'obj': obj})

    2). vim templates/index.html
        {% for i in page_obj.object_list %}
            <tr>
                <td>{{ i.id }}</td>
                <td>{{ i.name }}</td>
                <td>{{ i.password }}</td>
                <td>{{ i.email }}</td>
            </tr>
        {% endfor %}

    3). 例1 知識點
        (1): paginator = Paginator(user_list, 10)  對象的參數
        (2): obj = paginator.page(curent_page) 的方法  # 參數爲 : 要獲取的頁數
            obj 對象中的方法:
                {{ obj.has_next }}               是否有下一頁
                {{ obj.next_page_number }}       下一頁頁碼

                {{ obj.has_previous }}           是否有上一頁
                {{ obj.previous_page_number }}   上一頁頁碼

                {{ obj.object_list }}            分頁以後的數據列表
                {{ obj.number }}                 當前頁
                {{ obj.paginator }}   paginator 對象 就是 paginator = Paginator(list, nmber) 這個方法是爲了調用其下的方法
            注意: 這幾個方法不是在 Python 在中使用的, 而是在模板語法中調用的, 如 例 4.3 例子

2. 處理異常
    問題描述
        UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list:
        /laojia/reboot/opsweb/accounts/views.py:234: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'django.contrib.auth.models.User'> QuerySet.

        paginator = Paginator(user_list, self.paginate_by)

        這個是由於django,查詢出來多條記錄時,默認是無序排列的,因此 每查詢一次 分頁的 list 都是不同的。

    解決方法:
        查詢的時候,增長一個排序就能夠了
        user_list = Profile.objects.get_queryset().order_by('id')
            或者
        user_list = models.District.objects.all().order_by('id')

        可是這樣寫, 會佔用資源

3. 例2:
    3.1. 例二解釋
        (1): 處理 ?p 參數 不正確時 報錯
        (2): 添加 上一頁, 下一頁

    3.2. 修改視圖函數
        def users(request):
            from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
            # 導入 兩個 處理報錯的 模塊
            #   EmptyPage : 處理數字不正卻時報錯
            #   PageNotAnInteger : 處理不是數字報錯

            curent_page = request.GET.get('p', 1)  # 想獲取的頁數, 沒有指定就返回第一頁

            user_list = models.District.objects.all().order_by('id')
            paginator = Paginator(user_list,10)

            try:
                page_obj = paginator.page(curent_page)
            except EmptyPage as e:
                page_obj = paginator.page(1)
            except PageNotAnInteger as not_int_err:
                page_obj = paginator.page(1)

            return render(request, 'index.html', {'page_obj': page_obj})

    4.3. vim templates/index.html
        <center>
            <table border="1" cellspacing="0" width="500">
                <tr>
                    <th>ID</th>
                    <th>用戶名</th>
                    <th>密碼</th>
                    <th>郵箱</th>
                </tr>
                {% for i in page_obj.object_list %}
                <tr>
                    <td>{{ i.id }}</td>
                    <td>{{ i.name }}</td>
                    <td>{{ i.password }}</td>
                    <td>{{ i.email }}</td>
                </tr>
                {% endfor %}
            </table>
            <div>
                {% if page_obj.has_previous  %}
                    <a href="/users?p={{ page_obj.previous_page_number }}">上一頁</a>
                {% else %}
                    <a href="">上一頁</a>
                {% endif %}
                {% if page_obj.has_next  %}
                    <a href="/users?p={{ page_obj.next_page_number }}">下一頁</a>
                {% else %}
                    <a href="">下一頁</a>
                {% endif %}
            </div>
        </center>

    3.4. 例3 知識點總結
        (1): 使用了 列2 中的知識點 paginator.page(curent_page) 中的方法
        (2): 添加了兩個議程處理模塊


4. 例3:
    4.1. 介紹
        1). 使用 {{ page_obj.paginator }} 的方法
        2). 在頁面上添加的頁數
        3). 添加頁碼
        4). 添加 當前頁 與 尾頁

    4.2. 知識點
        1). {{ page_obj.paginator }} : page_obj 就是傳到 html 的對象 實際上就是 Paginator() 對象
        2). {{ page_obj.paginator }} : 的方法
            per_page :  每頁顯示條目數量
            count :    數據總個數
            num_pages : 總頁數
            page_range : 總頁數的索引範圍,如: 若是 總頁數是 11, name 這個值就是 (1,12) 因爲不取尾的緣故因此 11+1

            使用時加 .count 便可, 如 : {{ page_obj.paginator.count }}

    4.3. 視圖函數不變

    4.4. 修改 center 下的 div
        <div>
            {% if page_obj.has_previous  %}
                <a href="/users?p={{ page_obj.previous_page_number }}">上一頁</a>
            {% else %}
                <a href="">上一頁</a>
            {% endif %}
                {# 5.3. 新添加 內容, 顯示頁碼 #}
                {% for i in page_obj.paginator.page_range %}
                    <a href="/users?p={{ i }}">{{ i }}</a>
                {% endfor %}

            {% if page_obj.has_next  %}
                <a href="/users?p={{ page_obj.next_page_number }}">下一頁</a>
            {% else %}
                <a href="">下一頁</a>
            {% endif %}

            {# 5.3. 添加 當前頁 與 尾頁 #}
            <span>{{ page_obj.number }}/</span> {# 當前頁 #}
            <span>{{ page_obj.paginator.num_pages }}</span>  {# 總頁數 #}
        </div>

4. 缺點
    django 沒法解決頁碼過多的問題, 須要本身進行擴展html

相關文章
相關標籤/搜索