1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Django自定義實(shí)現(xiàn)分頁(yè)器

        共 17444字,需瀏覽 35分鐘

         ·

        2021-05-28 12:34

        目錄

        • 1、分析和推導(dǎo)

          • 1.1 當(dāng)前頁(yè)

          • 1.2 起始位置和終止位置

          • 1.3 添加按鈕傳遞頁(yè)碼數(shù)

        • 2、方法的封裝

          • 2.1 分頁(yè)器類

          • 2.2 視圖函數(shù)

          • 2.3 模板頁(yè)面


        前面的文章中分別介紹了 drf分頁(yè)器的使用Django分頁(yè)器的用法,其重點(diǎn)在于視圖函數(shù)和模板頁(yè)面如何利用自帶的分頁(yè)器的相關(guān)參數(shù)進(jìn)行數(shù)據(jù)傳遞和頁(yè)面渲染

        本文繼續(xù)介紹分頁(yè)器,即自定義分頁(yè)器如何實(shí)現(xiàn),其實(shí)也就是如何使用自定義的方式計(jì)算出和上面類似自帶的分頁(yè)器的相關(guān)參數(shù)值

        1、分析和推導(dǎo)

        分頁(yè)中的關(guān)鍵信息:當(dāng)前頁(yè)、每頁(yè)展示多少條、起始位置、終止位置

        1.1 當(dāng)前頁(yè)

        思路:瀏覽器攜帶頁(yè)碼發(fā)送get請(qǐng)求,獲取當(dāng)前頁(yè)信息。后端從get請(qǐng)求中獲取響應(yīng)的頁(yè)碼數(shù),查詢對(duì)應(yīng)數(shù)據(jù)并返回

        # 想訪問(wèn)哪一頁(yè)
        current_page = request.GET.get('page'1)  # 如果獲取不到當(dāng)前頁(yè)碼 就展示第一頁(yè)
        # 數(shù)據(jù)類型轉(zhuǎn)換,將獲取的字符串頁(yè)碼轉(zhuǎn)換成int
        try:
          current_page = int(current_page)
        except Exception:
            current_page = 1

        1.2 起始位置和終止位置

        每頁(yè)條數(shù)、起始位置、終止位置的推導(dǎo)

        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ān)系

        start_page = (current_page - 1) * per_page_num
        end_page = current_page * per_page_num

        最終基于頁(yè)碼查詢出當(dāng)前頁(yè)的數(shù)據(jù)

        # 每頁(yè)展示多少條
        per_page_num = 10
        # 起始位置
        start_page = (current_page - 1) * per_page_num
        # 終止位置
        end_page = current_page * per_page_num
        book_queryset = book_list[start_page:end_page]

        1.3 添加按鈕傳遞頁(yè)碼數(shù)

        總的頁(yè)碼數(shù)需要傳遞到頁(yè)面,總頁(yè)數(shù)與總數(shù)和每頁(yè)數(shù)有關(guān)系,例如

        總數(shù)據(jù)100 每頁(yè)展示10 需要10頁(yè)
        總數(shù)據(jù)101 每頁(yè)展示10 需要11頁(yè)
        總數(shù)據(jù)99  每頁(yè)展示10 需要10頁(yè)

        如何動(dòng)態(tài)計(jì)算到底需要多少頁(yè)呢?這里可以利用divmod方法來(lái)計(jì)算總數(shù)與每頁(yè)個(gè)數(shù)的商和余數(shù),余數(shù)不為0時(shí),把頁(yè)數(shù)加1

        # 分頁(yè)
        book_list = models.Book.objects.all()
        # 計(jì)算出到底需要多少頁(yè)
        all_count = book_list.count()
        page_count, more = divmod(all_count, per_page_num)  # 計(jì)算總數(shù)%每頁(yè)個(gè)數(shù)的商和余數(shù),余數(shù)不為0時(shí),把頁(yè)數(shù)+1
        if more:  # 有余數(shù)則總頁(yè)數(shù)加一
            page_count += 1

        關(guān)于頁(yè)碼布局,在制作頁(yè)碼個(gè)數(shù)的時(shí)候一般情況下都是奇數(shù)個(gè)頁(yè)碼,這更符合對(duì)稱美的標(biāo)準(zhǔn)

        最后,在后端把頁(yè)碼計(jì)算邏輯寫(xiě)出來(lái)動(dòng)態(tài)的傳給前端

        # 在后端把頁(yè)碼計(jì)算邏輯寫(xiě)出來(lái)傳給前端
        page_html = ''
        x = current_page
        if current_page < 6:  # 控制頁(yè)碼數(shù)量,當(dāng)小于6時(shí),不顯示負(fù)數(shù)頁(yè)碼
            current_page = 6
        for i in range(current_page - 5, current_page + 6):  # 顯示11個(gè)頁(yè)碼,被選中的在最中間
            if x == i:  # 高亮顯示被選中的那一個(gè)頁(yè)碼
                page_html += '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
            else:
                page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i)

        book_queryset = book_list[start_page:end_page]
        return render(request, 'ab_pl.html', locals())

        前端模板頁(yè)面接收

        <ul class="pagination">
            <li>
              <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
              </a>
            </li>
            {{ page_html|safe }}
            <li>
              <a href="#" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
              </a>
            </li>
        </ul>

        到這里,就實(shí)現(xiàn)了后端動(dòng)態(tài)的根據(jù)已有的數(shù)據(jù)并動(dòng)態(tài)的將頁(yè)碼數(shù)傳遞到了前端頁(yè)面渲染生成對(duì)應(yīng)的頁(yè)碼按鈕

        2、方法的封裝

        上面是自定義分頁(yè)器開(kāi)發(fā)流程的基本推導(dǎo)思路,最后將自定義分頁(yè)器進(jìn)行封裝

        2.1 分頁(yè)器類

        mypage.py

        class Pagination(object):
            def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
                """
                封裝分頁(yè)相關(guān)數(shù)據(jù)
                :param current_page: 當(dāng)前頁(yè)
                :param all_count:    數(shù)據(jù)庫(kù)中的數(shù)據(jù)總條數(shù)
                :param per_page_num: 每頁(yè)顯示的數(shù)據(jù)條數(shù)
                :param pager_count:  最多顯示的頁(yè)碼個(gè)數(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

                # 總頁(yè)碼
                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):
                # 如果總頁(yè)碼 < 11個(gè):
                if self.all_pager <= self.pager_count:
                    pager_start = 1
                    pager_end = self.all_pager + 1
                # 總頁(yè)碼  > 11
                else:
                    # 當(dāng)前頁(yè)如果<=頁(yè)面上最多顯示11/2個(gè)頁(yè)碼
                    if self.current_page <= self.pager_count_half:
                        pager_start = 1
                        pager_end = self.pager_count + 1
                    # 當(dāng)前頁(yè)大于5
                    else:
                        # 頁(yè)碼翻到最后
                        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標(biāo)簽
                page_html_list.append('''
                            <nav aria-label='Page navigation>'
                            <ul class='pagination'>
                        '''
        )
                first_page = '<li><a href="?page=%s">首頁(yè)</a></li>' % (1)
                page_html_list.append(first_page)

                if self.current_page <= 1:
                    prev_page = '<li class="disabled"><a href="#">上一頁(yè)</a></li>'
                else:
                    prev_page = '<li><a href="?page=%s">上一頁(yè)</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="#">下一頁(yè)</a></li>'
                else:
                    next_page = '<li><a href="?page=%s">下一頁(yè)</a></li>' % (self.current_page + 1,)
                page_html_list.append(next_page)

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

        2.2 視圖函數(shù)

        視圖函數(shù)中引用

        from utils.mypage import Pagination

        def get_books(request):
            book_queryset = models.Book.objects.all()
            current_page = request.GET.get("page"1)
            all_count = book_queryset.count()
            # 1 傳值生成對(duì)象
            page_obj = Pagination(current_page=current_page, all_count=all_count, per_page_num=10)
            # 2 直接對(duì)總數(shù)據(jù)進(jìn)行切片操作
            page_queryset = book_list[page_obj.start:page_obj.end]
            # 3 將page_queryset傳遞到頁(yè)面
            return render(request, 'booklist.html', locals())

        2.3 模板頁(yè)面

        模板頁(yè)面中渲染

        <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 %}
                   {#利用自定義分頁(yè)器直接顯示分頁(yè)器樣式#}
                    {{ page_obj.page_html|safe }}
                </div>
            </div>
        </div>
        瀏覽 103
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            淫色一区| 久久综合国产视频 | 国产日韩精品在线免费播放 | 91香蕉视频在线播放 | 五月天激情乱伦av | 免费黄色在线视频 | 少妇又色又紧又爽又刺激视频 | 按摩极致高潮2 | 欧美日韩一卡二卡三卡 | 日本一本二本三本在线观看 |