django中分頁器的使用方法(初、高級版本)

来源:https://www.cnblogs.com/Pluto-Love-Learn/p/18088226
-Advertisement-
Play Games

效果圖: 方法如下: 1.簡單版(較繁瑣但是直觀): 1.1 定義資料庫模型(models.py)中添加表 class ProductSample(models.Model): # 示例商品表 id = models.AutoField(db_column='ID', primary_key=Tru ...


效果圖:image
方法如下:

1.簡單版(較繁瑣但是直觀):

1.1 定義資料庫模型(models.py)中添加表

class ProductSample(models.Model):
    # 示例商品表
    id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    item_id = models.CharField(verbose_name="用戶ID",max_length=255, blank=True, null=True)
    title = models.TextField(verbose_name="標題",blank=True, null=True)
    pict_url = models.CharField(verbose_name="商品圖片鏈接",max_length=255, blank=True, null=True)
    category = models.TextField(verbose_name="類別",blank=True, null=True)
    brand_id = models.CharField(verbose_name="品牌ID",max_length=255, blank=True, null=True)
    seller_id = models.CharField(verbose_name="賣家ID",max_length=255, blank=True, null=True)

    def __str__(self):
        return self.title

    # class Meta:
    #     verbose_name = '商品信息'
    #     verbose_name_plural = verbose_name
    class Meta:
        managed = False
        db_table = 'product_sample'

1.2 路由(urls.py)中添加路徑

path("home/", views.home,name='home'), #主頁面

1.3 在視圖中(view.py)添加如下代碼

from .models import ProductSample #導入表
from django.utils.safestring import mark_safe

"""
需要修改如下代碼(替換為自己的表):
#數據總條數
total_count = 替換.objects.all().order_by('id').count()
#MySQL上獲取數據
documents = 替換.objects.all().order_by('id')[start:end]  # 指定按 id 欄位排序
"""
def home(request):
    """主頁面"""
    # 分頁器設計
    page = int(request.GET.get('page',1))
    size = 10    #每頁顯示10條
    start = (page - 1)*size
    end = page*size
    #數據總條數
    total_count = ProductSample.objects.all().order_by('id').count()
    #總頁碼
    total_page_count, div = divmod(total_count, size)
    if div:
        total_page_count +=1

    #MySQL上獲取數據
    documents = ProductSample.objects.all().order_by('id')[start:end]  # 指定按 id 欄位排序


    #計算初當前頁的前五頁和後五頁
    plus = 5
    if total_page_count <= 2 * plus + 1:
        #資料庫中的數據較少,沒有達到11頁
        start_page = 1
        end_page = total_page_count
    else:
        #資料庫中的數據較多 大於11頁

        #當前頁<5時
        if page <= plus:
            start_page = 1
            end_page = 2 * plus
        else:
            #當前頁>5
            #當前頁+5總頁碼
            if (page + plus ) > total_page_count:
                start_page = total_page_count - 2 * plus
                end_page = total_page_count
            else:
                start_page = page - plus
                end_page = page + plus
    #頁碼
    page_str_list = []

    #首頁
    page_str_list.append('<li><a href ="?page={}">首頁</a></li>'.format(1))

    #上一頁
    if page > 1:
        prev = '<li><a href ="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(page-1)
    else:
        prev = '<li><a href ="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(1)
    page_str_list.append(prev)
    #頁面
    for i in range(start_page,end_page+1):
        if i== page:
            ele = '<li class="active"><a href ="?page={}">{}</a></li>'.format(i,i)
        else:
            ele = '<li><a href ="?page={}">{}</a></li>'.format(i,i)
        page_str_list.append(ele)

    #下一頁
    if page < total_page_count:
        next_page = '<li><a href ="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(page+1)
    else:
        next_page = '<li><a href ="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(total_page_count)
    page_str_list.append(next_page)

    #尾頁
    page_str_list.append('<li><a href ="?page={}">尾頁</a></li>'.format(total_page_count))
    #搜索
    search_string ="""
    <li>
            <form style="display: inline-block;" method="get">
                <div class="input-group" style="width: 200px;display: inline-block;">
                    <input name="page"
                           style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0;"
                           type="text" class="form-control" placeholder="頁碼">
                    <span class="input-group-btn">
            <button style="border-radius: 0;" class="btn btn-default" type="submit">跳轉</button>
        </span>
                </div>
            </form>
    </li>
    """
    page_str_list.append(search_string)

    page_string = mark_safe("".join(page_str_list))
    return render(request,'home/home.html',locals())

1.4 html頁面使用分頁器

<div>
{% for d in documents %}
{{ d.pict_url }}
{{ d.title }}
<p>價格:${{ random_num }}</p>
{% endfor %}

  <nav aria-label="Page navigation">
     <ul class="pagination">
         {{ page_string }}
      </ul>
  </nav>
</div>
{% endblock %}

2 高級版(設置組件,可用於其他數據的分頁)

2.1 自定義分頁組件(在app裡面新建一個utils目錄,在utils裡面新建一個pagination.py文件)將下麵代碼添加到pagination.py文件中,使用說明如下:

缺點:搜索+分頁器時,不能將搜索的情況保留(下麵有改進版,按需設計)

"""
自定義的分頁組件,以後想要使用這個分頁組件,需要做如下幾件事:

#在視圖函數中:
from home.utils.pagination import Pagination

def home(request):
    # 1.根據自己的情況去篩選自己的數據
    queryset = ProductSample.objects.all()
    # 2.實例化分頁對象
    page_object = Pagination(request,queryset)
    page_queryset = page_object.page_queryset  #分頁後的數據
    page_string = page_object.html()  #頁碼

    return render(request,'home/home.html',locals())
    
#在HTML頁面中:
    {% for d in page_queryset %}
        <h4> {{ d.title }} </h4>
    {% endfor %}

    <ul class="pagination">
        {{ page_string }}
    </ul>
"""

from django.utils.safestring import mark_safe
class Pagination(object):

    def __init__(self,request,queryset,size = 10, plus=5, page_param="page"):
        """
        :param request: 請求的對象
        :param queryset: 符合條件的數據(對該數據進行分頁處理)
        :param size:每頁顯示多少條數據
        :param plus:顯示當前頁的前或後幾頁(頁碼)
        :param page_param:在URL中傳遞的獲取分頁的參數,例如:/home/?page=12
        """
        page = request.GET.get(page_param, "1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        self.page = page
        self.size = size  # 每頁顯示10條
        self.start = (page - 1) * size
        self.end = page * size
        self.page_queryset =queryset[self.start:self.end]

        # 數據總條數
        total_count = queryset.count()
        # 總頁碼
        total_page_count, div = divmod(total_count, size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        # 計算初當前頁的前五頁和後五頁
        if self.total_page_count <= 2 * self.plus + 1:
            # 資料庫中的數據較少,沒有達到11頁
            start_page = 1
            end_page = self.total_page_count
        else:
            # 資料庫中的數據較多 大於11頁

            # 當前頁<5時
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus
            else:
                # 當前頁>5
                # 當前頁+5總頁碼
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2 * self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus
        # 頁碼
        page_str_list = []

        # 首頁
        page_str_list.append('<li><a href ="?page={}">首頁</a></li>'.format(1))

        # 上一頁
        if self.page > 1:
            prev = '<li><a href ="/home/?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                self.page - 1)
        else:
            prev = '<li><a href ="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                1)
        page_str_list.append(prev)
        # 頁面
        for i in range(start_page, end_page + 1):
            if i == self.page:
                ele = '<li class="active"><a href ="?page={}">{}</a></li>'.format(i, i)
            else:
                ele = '<li><a href ="?page={}">{}</a></li>'.format(i, i)
            page_str_list.append(ele)

        # 下一頁
        if self.page < self.total_page_count:
            next_page = '<li><a href ="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.page + 1)
        else:
            next_page = '<li><a href ="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.total_page_count)
        page_str_list.append(next_page)

        # 尾頁
        page_str_list.append('<li><a href ="?page={}">尾頁</a></li>'.format(self.total_page_count))
        # 搜索
        search_string = """
            <li>
                    <form style="display: inline-block;" method="get">
                        <div class="input-group" style="width: 200px;display: inline-block;">
                            <input name="page"
                                   style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0;"
                                   type="text" class="form-control" placeholder="頁碼">
                            <span class="input-group-btn">
                    <button style="border-radius: 0;" class="btn btn-default" type="submit">跳轉</button>
                </span>
                        </div>
                    </form>
            </li>
            """
        page_str_list.append(search_string)
        page_string = mark_safe("".join(page_str_list))
        return page_string

3 高級版的升級(搜索+分頁)

修改pagination.py文件。原理:保留參數
問題:跳轉不能實現搜索的跳轉,處理辦法,結合Ajax來實現。

"""
自定義的分頁組件,以後想要使用這個分頁組件,需要做如下幾件事:

在視圖函數中:
from home.utils.pagination import Pagination

def home(request):

    # 1.根據自己的情況去篩選自己的數據
    queryset = ProductSample.objects.all()
    # 2.實例化分頁對象
    page_object = Pagination(request,queryset)
    page_queryset = page_object.page_queryset  #分頁後的數據
    page_string = page_object.html()  #頁碼

    return render(request,'home/home.html',locals())
    
    #在HTML頁面中:
    {% for d in page_queryset %}
        <h4> {{ d.title }} </h4>
    {% endfor %}

    <ul class="pagination">
        {{ page_string }}
    </ul>
"""

from django.utils.safestring import mark_safe
class Pagination(object):

    def __init__(self,request,queryset,size = 10, plus=5, page_param="page"):
        """
        :param request: 請求的對象
        :param queryset: 符合條件的數據(對該數據進行分頁處理)
        :param size:每頁顯示多少條數據
        :param plus:顯示當前頁的前或後幾頁(頁碼)
        :param page_param:在URL中傳遞的獲取分頁的參數,例如:/home/?page=12
        """

        from  django.http.request import QueryDict
        import copy
        query_dict = copy.deepcopy(request.GET)
        query_dict._mutable = True
        self.query_dict = query_dict
        self.page_param = page_param


        page = request.GET.get(page_param, "1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        self.page = page
        self.size = size  # 每頁顯示10條
        self.start = (page - 1) * size
        self.end = page * size
        self.page_queryset =queryset[self.start:self.end]

        # 數據總條數
        total_count = queryset.count()
        # 總頁碼
        total_page_count, div = divmod(total_count, size)
        if div:
            total_page_count += 1
        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        # 計算初當前頁的前五頁和後五頁
        if self.total_page_count <= 2 * self.plus + 1:
            # 資料庫中的數據較少,沒有達到11頁
            start_page = 1
            end_page = self.total_page_count
        else:
            # 資料庫中的數據較多 大於11頁

            # 當前頁<5時
            if self.page <= self.plus:
                start_page = 1
                end_page = 2 * self.plus
            else:
                # 當前頁>5
                # 當前頁+5總頁碼
                if (self.page + self.plus) > self.total_page_count:
                    start_page = self.total_page_count - 2 * self.plus
                    end_page = self.total_page_count
                else:
                    start_page = self.page - self.plus
                    end_page = self.page + self.plus
        # 頁碼
        page_str_list = []

        self.query_dict.setlist(self.page_param,[1])
        # 首頁
        page_str_list.append('<li><a href ="?{}">首頁</a></li>'.format(self.query_dict.urlencode()))

        # 上一頁
        if self.page > 1:
            self.query_dict.setlist(self.page_param, [self.page - 1])
            prev = '<li><a href ="?{}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li><a href ="?{}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                self.query_dict.urlencode())
        page_str_list.append(prev)
        # 頁面
        for i in range(start_page, end_page + 1):
            if i == self.page:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li class="active"><a href ="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            else:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li><a href ="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            page_str_list.append(ele)

        # 下一頁
        if self.page < self.total_page_count:
            self.query_dict.setlist(self.page_param, [self.page + 1])
            next_page = '<li><a href ="?{}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            next_page = '<li><a href ="?{}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.query_dict.urlencode())
        page_str_list.append(next_page)

        # 尾頁
        self.query_dict.setlist(self.page_param, [self.total_page_count])
        page_str_list.append('<li><a href ="?{}">尾頁</a></li>'.format(self.query_dict.urlencode()))
        # 搜索
        search_string = """
            <li>
                    <form style="display: inline-block;" method="get">
                        <div class="input-group" style="width: 200px;display: inline-block;">
                            <input name="page"
                                   style="position: relative;float: left;display: inline-block;width: 80px;border-radius: 0;"
                                   type="text" class="form-control" placeholder="頁碼">
                            <span class="input-group-btn">
                    <button style="border-radius: 0;" class="btn btn-default" type="submit">跳轉</button>
                </span>
                        </div>
                    </form>
            </li>
            """
        page_str_list.append(search_string)
        page_string = mark_safe("".join(page_str_list))
        return page_string
不甘平凡,努力活出自己的人生!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 雲原生技術正重塑IT領域,本文深度剖析了其發展歷程、核心概念、生態系統及實踐案例,展望未來趨勢,揭示了這一技術如何引領企業轉型與創新。 關註【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人 ...
  • Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹如何運用`QProcess`組件實現針對進程的控制管理等。當你在使用Qt進行跨平臺應用程式開發時,經常需要與外部進... ...
  • 對於程式員來說這個單詞完全擁有另外一個含義,Spring指的是一個開源項目,而這個項目非常厲害。而Spring與JSR、JarkataEE淵源頗深。 ...
  • 剛做完一道模板A*,看到這題我直接小腦萎縮了... 阿米諾斯!這怎麼用A*?!——剛開題的我 beeeeeeeeee like 甚至比模板簡單(這是綠的...) 其實會是會但是紙張的是這玩意我不會搞估價函數我草! 然後突然想到能不能把這個狀態下有多少個數字不在目標位置作為估價函數? 我喜歡 \(ID ...
  • 引言 在JDK1.2之前Java並沒有提供軟引用、弱引用和虛引用這些高級的引用類型。而是提供了一種基本的引用類型,稱為Reference。並且當時Java中的對象只有兩種狀態:被引用和未被引用。當一個對象被引用時,它將一直存在於記憶體中,直到它不再被任何引用指向時,才會被垃圾回收器回收。而被引用也就是 ...
  • 拓展閱讀 Devops-01-devops 是什麼? Devops-02-Jpom 簡而輕的低侵入式線上構建、自動部署、日常運維、項目監控軟體 代碼質量管理 SonarQube-01-入門介紹 項目管理平臺-01-jira 入門介紹 缺陷跟蹤管理系統,為針對缺陷管理、任務追蹤和項目管理的商業性應用軟 ...
  • 概述:在C++中,序列點是表達式中確保求值順序的點。其缺失可能導致未定義行為。基礎功能示例演示了自增運算符的序列點,而高級功能示例展示了函數調用的序列點,有助於避免不確定行為。在編寫代碼時遵循序列點規則是確保程式行為可預測的關鍵。 在C++中,序列點是在表達式中保證求值順序的點。未定義的行為通常涉及 ...
  • 概述:C++中的對象切片指通過將派生類對象賦值給基類對象,導致派生部分被“切掉”,只保留基類部分。這可能發生在值傳遞、賦值等操作中。對象切片的基礎功能示例展示了派生類對象賦值給基類對象時的現象,而高級功能示例則展示了通過基類指針實現派生類對象的訪問和多態。 對象切片(Object Slicing)是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...