django中的自定義分頁器

1.什么是自定義分頁器

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

創(chuàng)新互聯(lián)公司是一家企業(yè)級云計算解決方案提供商,超15年IDC數(shù)據中心運營經驗。主營GPU顯卡服務器,站群服務器,西部信息機房,海外高防服務器,成都機柜租用,動態(tài)撥號VPS,海外云手機,海外云服務器,海外服務器租用托管等。

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

如上所說:為了將數(shù)據分成多頁進行展示,分別閱讀,方便查詢!

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

3.1 自定義分頁器推導過程

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

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

其次我們還需要知道一個點,queryset對象是支持索引取值和切片操作的,但是不支持負數(shù)索引情況。

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

current_page = request.GET.get("page",1)  # 獲取用戶想訪問的頁碼  如果沒有 默認展示第一頁
try:  # 由于后端接受到的前端數(shù)據是字符串類型所以我們這里做類型轉換處理加異常捕獲
  current_page = int(current_page)
except Exception as e:
  current_page = 1
# 還需要定義頁面到底展示幾條數(shù)據
per_page_num = 10  # 一頁展示10條數(shù)據

# 需要對總數(shù)據進行切片操作 需要確定切片起始位置和終止位置
start_page = ? 
end_page = ?
"""
下面需要研究current_page、per_page_num、start_page、end_page四個參數(shù)之間的數(shù)據關系
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
可以很明顯的看出規(guī)律
start_page = (current_page - 1) * per_page_num
end_page =  current_page* per_page_num
"""

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

一共需要從數(shù)據庫取出的數(shù)據一共有多少條!??!

此時,我們就需要用到python中的一個內置方法divmod:它是功能是一個數(shù)除以另一個數(shù)時,返回余數(shù)和商?。∪纾?/p>

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

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

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

def book(request):
    if request.method == 'GET':
        current_page = request.GET.get('page',1) # 獲取用戶需要訪問的頁面,如果沒有默認返回1
    try:   #異常捕獲,因為前端返回的都是字符串,需要把他們都轉成數(shù)字類型,方便下面做運算操作
        current_page = int(current_page)
    except Exception as e:
        current_page = 1  # 用戶輸入啥字母等也默認為1
    per_page_num = 10  #每頁展示多少條數(shù)據
    start_page = (current_page - 1) * per_page_num  #當前頁數(shù)起始數(shù)據
    end_page = current_page * per_page_num  #當前頁結束數(shù)據
    book_num = models.Book.objects.all() #將所有數(shù)據查詢出來
    all_count = book_num.count()  # 統(tǒng)計一共有多少數(shù)據
    num,more = divmod(all_count,per_page_num)  #divmod方法計算需要的總頁數(shù)
    if more:
        all_page = num + 1 #more為余數(shù),余為0,則剛剛好是num頁數(shù),不為0,則頁數(shù)加1
    # 然后我們需要在html頁面的分頁器標簽部分,for循環(huán)一下總共需要的num頁數(shù),但是有一個問題是,前端無法使用range()
    # 這就需要我們在后端進行循環(huán),再傳到前端
    html = ''
    a = current_page # 為了下面頁碼高亮調整
    if current_page <6:  #當頁面小于6時,固定在6上面,為下面的for處理不出現(xiàn)頁碼負數(shù)
        current_page = 6
    # 訪問第6頁時,只會顯示當前頁-5和+6的底部頁碼數(shù),但是當頁面小于6時,頁碼會出現(xiàn)0甚至負數(shù),所有我們需要對頁面進行一個設置,就是上述的a
    for i in range(current_page-5,current_page+6):
        if a == i:
            # 當前頁的頁面高亮顯示
            html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
        else:
            html += '<li><a href="?page=%s">%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="#" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
      </a>
    </li>
        {{ html|safe }}
    <li>
      <a href="#" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
      </a>
    </li>
  </ul>
</nav>

3.2 自定義分頁器封裝代碼

封裝好的分液器
class Pagination(object):
    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
        """
        封裝分頁相關數(shù)據
        :param current_page: 當前頁
        :param all_count:    數(shù)據庫中的數(shù)據總條數(shù)
        :param per_page_num: 每頁顯示的數(shù)據條數(shù)
        :param pager_count:  最多顯示的頁碼個數(shù)
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 總頁碼
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果總頁碼 < 11個:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 總頁碼  > 11
        else:
            # 當前頁如果<=頁面上最多顯示11/2個頁碼
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 當前頁大于5
            else:
                # 頁碼翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul標簽
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首頁</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一頁</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一頁</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一頁</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一頁</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾頁</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加標簽
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

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中的自定義分頁器
標題路徑:http://m.kartarina.com/article42/dsogiec.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供網站建設、網站排名、用戶體驗、App開發(fā)、建站公司軟件開發(fā)

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網頁設計公司
主站蜘蛛池模板: 无码专区中文字幕无码| 亚洲Av无码一区二区二三区 | 国产成人无码a区在线视频 | 国产精品无码无卡无需播放器| 永久免费无码网站在线观看个| 国产aⅴ无码专区亚洲av麻豆 | 国产成人无码AV在线播放无广告| a级毛片免费全部播放无码| WWW久久无码天堂MV| 无码人妻一区二区三区在线| 亚洲中文字幕无码中文字| 性无码专区无码片| 国产色无码精品视频国产| 无码熟妇人妻在线视频| 亚洲AV无码AV吞精久久| 少妇无码一区二区三区免费| 亚洲精品无码成人片久久| 日韩综合无码一区二区| 亚洲成a∨人片在无码2023| 无码人妻丰满熟妇区免费 | 亚洲精品无码专区2| 一本大道在线无码一区| 一本色道无码不卡在线观看 | 亚洲av无码乱码在线观看野外| 久久Av无码精品人妻系列| 亚洲熟妇无码AV| 久久久久久人妻无码| 国产精品亚洲а∨无码播放| 久久亚洲AV永久无码精品| 国产精品无码aⅴ嫩草| 国产在线拍揄自揄拍无码视频| 无码任你躁久久久久久久| 少妇无码太爽了在线播放| 国产成人无码免费视频97| 无码一区二区三区中文字幕| 亚洲AV成人无码网站| 无码人妻aⅴ一区二区三区| 日韩视频无码日韩视频又2021| 国外AV无码精品国产精品| 无码人妻少妇久久中文字幕 | 无码一区二区三区免费|