🍖Django分頁器

一.分頁器簡介

當數據量很是大時, 咱們不可能把全部的數據都放在同一頁中, 因而就有了分頁的概念, 將數據像書同樣每一頁規定可容納多少條數據, 運用到Django中的分頁組件, 它實際上是Django內置的一個類html

二.Paginator對象與Page類對象

1.如何獲得這兩個類對象

  • 導入分頁類
from django.core.paginator import Paginator
  • Paginator類對象
# 語法僞代碼
paginator = Paginator([要分頁的數據],[每頁顯示條數])
# 示例
paginator = Paginator(shop_list,10)
  • Page類對象
# 語法僞代碼
page = paginator.page([第幾頁])
# 示例
page = paginator.page(2)  # 獲取第二頁對象

2.Paginator類對象屬性和方法

  • 屬性
屬性名 說明
count 返回數據總條數
num_pages 返回分頁以後的總頁數
per_page 每頁顯示的條數
page_range 返回分頁後頁碼的列表
  • 方法
方法名 說明
page(self, number) 返回地number頁的page類實例對象

3.Page類對象屬性和方法

  • 屬性
屬性名 說明
number 返回當前頁頁碼
object_list 返回當前頁的數據列表
paginator 返回對應的Paginator類對象
  • 方法
方法名 說明
has_previous( ) 判斷當前頁是否有上一頁
has_next( ) 判斷當前頁是否有下一頁
previous_page_number( ) 返回前一頁頁碼
next_page_number( ) 返回下一頁頁碼

三.建立表並插入數據(準備工做)

1.建立模型類

class Shop(models.Model):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    nums = models.IntegerField(verbose_name='商品剩餘')

    def __str__(self):
        return self.name

2.使用for循環批量插入數據

for i in range(1,151):
    models.Shop.objects.create(name=f'商品{i}',price=10+int(f'{i}'),nums=f'{random.randint(1,15)}')

每循環一次就鏈接一次數據庫, 效率低前端

3.bulk_create( ) : 批量插入數據

import random
shop_list = []
for i in range(1,151):
    book = models.Shop(name=f'商品{i}',price=10+int(f'{i}'),nums=f'{random.randint(1,15)}')
    shop_list.append(book)
models.Shop.objects.bulk_create(shop_list,10)  # 第二個參數是每次插入的條數

能夠指定每次插入的條數, 效率高python

4.將初始數據渲染到頁面

  • page_shop.html 文件
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-info">
                <div class="panel-heading text-center">商品信息表</div>
                <div class="panel-body">
                    <table class="table table-striped table-hover">
                        <thead>
                            <tr>
                                <th>編號</th>
                                <th>商品名</th>
                                <th>價格</th>
                                <th>剩餘個數</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for obj in shop_obj %}
                                <tr>
                                    <th>{{ obj.id }}</th>
                                    <th>{{ obj.name }}</th>
                                    <th>{{ obj.price }}</th>
                                    <th>{{ obj.nums }}</th>
                                </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
  • 展現效果

以上是沒有沒有分頁的效果, 一頁翻不到頭, 使用起來不方便git

四.分頁器完整用法

1.實現需求

  • 每頁顯示15條數據
  • 頁碼列表只展現11頁, 隨着當前頁變化
  • 當前頁爲第一頁則禁用''上一頁''按鈕
  • 當前頁爲最後頁則禁用''下一頁''按鈕
  • 當前頁按鈕處於激活狀態

2.效果展現

  • 總體展現

  • 分頁按鈕展現

3.代碼實現

  • 路由層 urls.py 文件
re_path('^page_shop/', views.page_shop)
  • 視圖層 views.py 文件

視圖層須要傳給前端使用的三個參數(核心) :數據庫

  • 分頁後的paginator對象,用來展現數據
  • 分頁後的頁碼列表,咱們規定每次展現11個頁碼,中間頁碼爲當前頁,左右頁碼隨之變化(這裏須要注意前11頁和後11頁)
  • 收到前端點擊的頁碼,咱們要返回該頁碼(page)對象(注意小於或超出中頁碼的狀況)
from django.shortcuts import render, HttpResponse, redirect
from app01 import models

def page_shop(request):
    # 🔰1.分頁後的paginator對象
    current_page = int(request.GET.get('page_num',1))  # 獲取用戶點擊的頁碼,沒有則默認第一頁
    shop_list = models.Shop.objects.all()              # 獲取全部的商品對象列表
    paginator = Paginator(shop_list,15)                # 每頁展現15條商品信息

    # 🔰2.頁碼列表
    # 若是分頁後的總頁數大於11
    if paginator.num_pages > 11:
        # 總共11頁,取中間頁(當前頁)來判斷是不是第1~11頁
        if current_page - 5 < 1:
            # 1~11頁碼列表
            page_range = range(1, 12)
        # 取11頁的中間頁(當前頁)判斷是不是最後11頁
        elif current_page + 5 > paginator.num_pages:
            # 最後11頁頁碼列表
            page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
        else:
            # 若是不是前面11頁,也不是後面11頁,那麼頁碼列表動態就會隨着當前列表動態加減
            page_range = range(current_page - 5, current_page + 5)
    else:
        # 總頁數小於11就直接所有顯示
        page_range = paginator.page_range

    # 🔰3.page對象
    try:
        # 若是前端傳過來的頁碼小於分頁後的最小頁碼或者大於最大頁碼就會報錯
        page = paginator.page(current_page)
    except Exception as E:
        current_page = 1  # 若是超出或小於咱們就讓其默認展現第一頁
        page = paginator.page(current_page)

    return render(request, 'page.html', {'page_range': page_range, 'page': page, 'current_page': current_page})
  • 模板層 page.html 文件
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-info">
                <div class="panel-heading text-center">商品信息表</div>
                <div class="panel-body">
                    <table class="table table-striped table-hover">
                        <thead>
                            <tr>
                                <th>編號</th>
                                <th>商品名</th>
                                <th>價格</th>
                                <th>剩餘個數</th>
                            </tr>
                        </thead>
                        <tbody>
                            {# 展現當前頁的全部數據 #}
                            {% for obj in page.object_list %}
                                <tr>
                                    <th>{{ obj.id }}</th>
                                    <th>{{ obj.name }}</th>
                                    <th>{{ obj.price }}</th>
                                    <th>{{ obj.nums }}</th>
                                </tr>
                            {% endfor %}
                        </tbody>
                    </table>
{# -------------------上面爲數據渲染,下面爲頁碼列表-------------------- #}                   
                    <div class="text-center">
                        <nav aria-label="Page navigation">
                            <ul class="pagination">
                                {# 判斷當前頁是否有上一頁(針對向左的箭頭按鈕) #}
                                {% if page.has_previous %}
                                    <li>
                                        {# 若是有上一頁就跳到上一頁 #}
                                        <a href="/page_shop/?page_num={{ page.previous_page_number }}"
                                           aria-label="Previous">
                                            <span aria-hidden="true">&laquo;</span>
                                        </a>
                                    </li>
                                {% else %}
                                    {# 若是沒有上一頁,就將該按鈕禁用 #}
                                    <li class="disabled">
                                        <a href="" aria-label="Previous">
                                            <span aria-hidden="true">&laquo;</span>
                                        </a>
                                    </li>
                                {% endif %}

                                {# 從頁碼列表中循環取出頁碼與當前頁作對比 #}
                                {% for foo in page_range %}
                                    {% if current_page == foo %}
                                        {# 若是是當前頁,就將當前頁按鈕變成激活狀態(藍色) #}
                                        <li class="active"><a href="/page_shop/?page_num={{ foo }}">{{ foo }}</a></li>
                                    {% else %}
                                        {# 若是不是則不變色 #}
                                        <li><a href="/page_shop/?page_num={{ foo }}">{{ foo }}</a></li>
                                    {% endif %}

                                {% endfor %}

                                {# 判斷但前頁是否有下一頁(針對向右的箭頭按鈕) #}
                                {% if page.has_next %}
                                    <li>
                                        {# 若是有則跳轉到下一頁 #}
                                        <a href="/page_shop/?page_num={{ page.next_page_number }}" aria-label="Next">
                                            <span aria-hidden="true">&raquo;</span>
                                        </a>
                                    </li>
                                {% else %}
                                    {# 沒有下一頁則將按鈕禁用 #}
                                    <li class="disabled">
                                        <a href="" aria-label="Next">
                                            <span aria-hidden="true">&raquo;</span>
                                        </a>
                                    </li>
                                {% endif %}

                            </ul>
                        </nav>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

以上視圖層和模板層能夠當固定模板來使用, 只須要修改模型類(你的數據)django

相關文章
相關標籤/搜索