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 8、WPF、Prism.DryIoc、MVVM設計模式、Blazor以及MySQL資料庫構建的企業級工作流系統的WPF客戶端框架-AIStudio.Wpf.AClient 6.0。 項目介紹 框架採用了 Prism 框架來實現 MVVM 模式,不僅簡化了 MVVM 的典型 ...
  • 先看一下效果吧: 我們直接通過改造一下原版的TreeView來實現上面這個效果 我們先創建一個普通的TreeView 代碼很簡單: <TreeView> <TreeViewItem Header="人事部"/> <TreeViewItem Header="技術部"> <TreeViewItem He ...
  • 1. 生成式 AI 簡介 https://imp.i384100.net/LXYmq3 2. Python 語言 https://imp.i384100.net/5gmXXo 3. 統計和 R https://youtu.be/ANMuuq502rE?si=hw9GT6JVzMhRvBbF 4. 數 ...
  • 本文為大家介紹下.NET解壓/壓縮zip文件。雖然解壓縮不是啥核心技術,但壓縮性能以及進度處理還是需要關註下,針對使用較多的zip開源組件驗證,給大家提供個技術選型參考 之前在《.NET WebSocket高併發通信阻塞問題 - 唐宋元明清2188 - 博客園 (cnblogs.com)》講過,團隊 ...
  • 之前寫過兩篇關於Roslyn源生成器生成源代碼的用例,今天使用Roslyn的代碼修複器CodeFixProvider實現一個cs文件頭部註釋的功能, 代碼修複器會同時涉及到CodeFixProvider和DiagnosticAnalyzer, 實現FileHeaderAnalyzer 首先我們知道修 ...
  • 在軟體行業,經常會聽到一句話“文不如表,表不如圖”說明瞭圖形在軟體應用中的重要性。同樣在WPF開發中,為了程式美觀或者業務需要,經常會用到各種個樣的圖形。今天以一些簡單的小例子,簡述WPF開發中幾何圖形(Geometry)相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 在 C# 中使用 RabbitMQ 通過簡訊發送重置後的密碼到用戶的手機號上,你可以按照以下步驟進行 1.安裝 RabbitMQ 客戶端庫 首先,確保你已經安裝了 RabbitMQ 客戶端庫。你可以通過 NuGet 包管理器來安裝: dotnet add package RabbitMQ.Clien ...
  • 1.下載 Protocol Buffers 編譯器(protoc) 前往 Protocol Buffers GitHub Releases 頁面。在 "Assets" 下找到適合您系統的壓縮文件,通常為 protoc-{version}-win32.zip 或 protoc-{version}-wi ...
  • 簡介 在現代微服務架構中,服務發現(Service Discovery)是一項關鍵功能。它允許微服務動態地找到彼此,而無需依賴硬編碼的地址。以前如果你搜 .NET Service Discovery,大概率會搜到一大堆 Eureka,Consul 等的文章。現在微軟為我們帶來了一個官方的包:Micr ...
  • ZY樹洞 前言 ZY樹洞是一個基於.NET Core開發的簡單的評論系統,主要用於大家分享自己心中的感悟、經驗、心得、想法等。 好了,不賣關子了,這個項目其實是上班無聊的時候寫的,為什麼要寫這個項目呢?因為我單純的想吐槽一下工作中的不滿而已。 項目介紹 項目很簡單,主要功能就是提供一個簡單的評論系統 ...