首頁 > 軟體

django中的自定義分頁器的實現範例

2022-08-15 10:02:25

1.什麼是自定義分頁器

當我們需要在前端頁面展示的資料太多的時候,我們總不能將資料展示在一頁上面吧!這時,我們就需要自定義一個分頁器,將資料分成特定的頁數進行展示,每一頁展示固定條數的資料!

2.為什麼要用自定義分頁器

如上所說:為了將資料分成多頁進行展示,分別閱讀,方便查詢!

3.如何使用自定義分頁器

3.1 自定義分頁器推導過程

雖然!我們有一個封裝好的分頁器原始碼,用的時候只需要cv大法就行,但是作為一名優秀的程式猿!!我們還是需要知道底層的邏輯是不是!

我們需要明確的是,前端向後端請求的常用方式為get和post請求。分頁的時候,我們應該採用get請求的方式給後端傳輸您需要轉到的頁數!!

其次我們還需要知道一個點,queryset物件是支援索引取值和切片操作的,但是不支援負數索引情況。

接下來,我們來推導一下分頁器的形成的邏輯:

current_page = request.GET.get("page",1)  # 獲取使用者想存取的頁碼  如果沒有 預設展示第一頁
try:  # 由於後端接受到的前端資料是字串型別所以我們這裡做型別轉換處理加異常捕獲
  current_page = int(current_page)
except Exception as e:
  current_page = 1
# 還需要定義頁面到底展示幾條資料
per_page_num = 10  # 一頁展示10條資料

# 需要對總資料進行切片操作 需要確定切片起始位置和終止位置
start_page = ? 
end_page = ?
"""
下面需要研究current_page、per_page_num、start_page、end_page四個引數之間的資料關係
per_page_num = 10
current_page                start_page                  end_page
    1                           0                           10
    2                           10                          20
    3                           20                          30  
    4                           30                          40

per_page_num = 5
current_page                start_page                  end_page
    1                           0                           5
    2                           5                           10
    3                           10                          15  
    4                           15                          20
可以很明顯的看出規律
start_page = (current_page - 1) * per_page_num
end_page =  current_page* per_page_num
"""

我們研究完當前頁(current_page)、每頁展示的資料條數(per_page_num)、每頁資料的起始位置(start_page)和結束位置(end_page)之後,我們還需要知道的最重要的一點是:

一共需要從資料庫取出的資料一共有多少條!!!

此時,我們就需要用到python中的一個內建方法divmod:它是功能是一個數除以另一個數時,返回餘數和商!!如:

>>> divmod(100,10)
(10, 0)  # 10頁
>>> divmod(101,10)
(10, 1)  # 11頁
>>> divmod(99,10)
(9, 9)  # 10頁
# 餘數只要不是0就需要在第一個數位上加一

我們可以用它來判斷我們一共需要多少頁!

後端自定義分頁器邏輯詳解:

def book(request):
    if request.method == 'GET':
        current_page = request.GET.get('page',1) # 獲取使用者需要存取的頁面,如果沒有預設返回1
    try:   #異常捕獲,因為前端返回的都是字串,需要把他們都轉成數位型別,方便下面做運算操作
        current_page = int(current_page)
    except Exception as e:
        current_page = 1  # 使用者輸入啥字母等也預設為1
    per_page_num = 10  #每頁展示多少條資料
    start_page = (current_page - 1) * per_page_num  #當前頁數起始資料
    end_page = current_page * per_page_num  #當前頁結束資料
    book_num = models.Book.objects.all() #將所有資料查詢出來
    all_count = book_num.count()  # 統計一共有多少資料
    num,more = divmod(all_count,per_page_num)  #divmod方法計算需要的總頁數
    if more:
        all_page = num + 1 #more為餘數,餘為0,則剛剛好是num頁數,不為0,則頁數加1
    # 然後我們需要在html頁面的分頁器標籤部分,for迴圈一下總共需要的num頁數,但是有一個問題是,前端無法使用range()
    # 這就需要我們在後端進行迴圈,再傳到前端
    html = ''
    a = current_page # 為了下面頁碼高亮調整
    if current_page <6:  #當頁面小於6時,固定在6上面,為下面的for處理不出現頁碼負數
        current_page = 6
    # 存取第6頁時,只會顯示當前頁-5和+6的底部頁碼數,但是當頁面小於6時,頁碼會出現0甚至負數,所有我們需要對頁面進行一個設定,就是上述的a
    for i in range(current_page-5,current_page+6):
        if a == i:
            # 當前頁的頁面高亮顯示
            html += '<li class="active"><a href="?page=%s" rel="external nofollow"  rel="external nofollow" >%s</a></li>' % (i, i)
        else:
            html += '<li><a href="?page=%s" rel="external nofollow"  rel="external nofollow" >%s</a></li>' % (i, i)
    book_queryset = book_num[start_page:end_page]
    return render(request,'book.html',locals())

前端頁面部分:
<nav aria-label="Page navigation">
  <ul class="pagination">
    <li>
      <a href="#" rel="external nofollow"  rel="external nofollow"  aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
        {{ html|safe }}
    <li>
      <a href="#" rel="external nofollow"  rel="external nofollow"  aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>

3.2 自定義分頁器封裝程式碼

封裝好的分液器

3.3 封裝好分頁器的使用

後端

 def get_book(request):
   book_list = models.Book.objects.all()
   current_page = request.GET.get("page",1)
   all_count = book_list.count()
   page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
   page_queryset = book_list[page_obj.start:page_obj.end]
   return render(request,'booklist.html',locals())

前端

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book in page_queryset %}
            <p>{{ book.title }}</p>
            {% endfor %}
            {{ page_obj.page_html|safe }}
        </div>
    </div>
</div>

 到此這篇關於django中的自定義分頁器的實現範例的文章就介紹到這了,更多相關django 自定義分頁器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com