Django母嬰商城項目實踐(九)- 商品列表頁模塊

9、商品列表頁模塊

1、業務邏輯

  • 商品模塊分為:商品列表頁商品詳情頁

  • 商品列表頁將所有商品按照一定的規則排序展示,用于可以從銷量、價格、上架時間和收藏數量設置商品的排序方式,并且在商品左側設置分類列表,選擇某一個分類可以篩選出對應的商品信息。

    在這里插入圖片描述

  • 商品列表頁設有商品搜索功能和導航欄,網頁頂部下方劃分為3個部分:分類列表、排序設置和商品列表,當在搜索欄搜索每個商品時,商品列表會展示符合搜索條件的數據,這些數據還可以分類顯示、排序設置和分頁查詢,所以商品列表頁需實現商品關鍵字查詢、商品分類篩選、商品排序設置和分頁顯示,同時這四種方式可以任意組合并且互不干擾。

  • 數據查詢適合使用GET、POST請求實現,則針對4種查詢方式分別設置請求參數n、t、s 和 p,其中n 表示商品搜索功能的關鍵字、t 表示用于查詢某一個分頁的商品、s 用設置商品的排序方式、p 用于設置商品信息的頁數。

2、功能實現

  • 項目應用 commodity 下的 urls.py:
from django.urls import path
from .views import *urlpatterns = [path('', commodityView, name='commodity'),   # 商品列表頁path('detail/<int:id>.html', detailView, name='detail'),   # 商品詳情頁
]
  • 項目應用 commodity 下的 views.py:
from django.shortcuts import render
from .models import CommodityInfos, Types
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage  # 分頁def commodityView(request):'''商品列表頁的業務邏輯:param request: 請求對象:return: 渲染頁面內容'''title = '商品列表'   # 頁面的標題# 查詢分類的數據typeLists = Types.objects.all()  # 獲取所有的商品分類firsts_lists = Types.objects.values('firsts').distinct()  # 獲取不重復的一級分類# 查詢所有商品的數據commodityInfos = CommodityInfos.objects.all()# 獲取搜索關鍵字search = request.GET.get('q', '').strip()if search:   # 搜索關鍵字不為空,則查詢商品名字中包含關鍵字的數據commodityInfos = commodityInfos.filter(name__contains=search)# 獲取選擇的二級分類名稱utype = request.GET.get('t', '')if utype:  # 選擇了二級分類名稱不為空,則查詢商品分類等于該名稱的數據commodityInfos = commodityInfos.filter(types=utype)# 獲取選擇的排序字段操作choice = request.GET.get('s', '')# 獲取排序字段映射(傳遞的排序操作:排序字段條件)sort_map = {'sold0': 'sold',  # 銷量升序'sold1': '-sold',   # 銷量降序'discount0': 'discount',  # 價格升序'discount1': '-discount', # 價格降序'created0': 'created',  # 最新升序'created1': '-created', # 最新降序'likes0': 'likes',  # 收藏升序'likes1': '-likes', # 收藏降序}if choice and choice in sort_map:  # 判斷排序字段是否存在,且在排序字段映射的字典中,在根據排序字段進行排序commodityInfos = commodityInfos.order_by(sort_map[choice])'''方式1:搜索 + 分類 + 按字段排序:參數 q + t + shttp://127.0.0.1:8003/commodity.html?q=%E5%AE%9D%E5%AE%9D&t=%E5%AE%9D%E5%AE%9D%E8%BE%85%E9%A3%9F&s=likes1方式2:分類 + 按字段排序:q='' + t + shttp://127.0.0.1:8003/commodity.html?q=&t=%E5%AE%9D%E5%AE%9D%E8%BE%85%E9%A3%9F&s=likes1'''# p 分頁功能:獲取當前頁碼數pages = request.GET.get('p', 1)# 1 創建分頁對象paginator = Paginator(commodityInfos, 6)# 2 向模板傳遞分頁對象try:pageObj = paginator.page(pages)  # 對數據進行切片處理except PageNotAnInteger:  # 頁面數不為整數(用戶隨機修改p的值,不是整數)pageObj = paginator.page(1)except EmptyPage:  # 頁面數超過最大值pageObj = paginator.page(paginator.num_pages)  # 獲取最大頁數return render(request, 'commodity.html', locals())

3、分頁功能的機制和原理

  • Django 為開發者提供了內置的分頁功能,開發者無須自己實現數據分頁功能,只需調用 Django 內置分頁功能的函數即可實現,實現數據的分頁功能需要考慮多方面的因素,分別說明如下:

    • 當前用戶訪問的頁數是否存在上(下)一頁。
    • 訪問的頁數是否超出頁數上限。
    • 數據如何接頁截取,如何設置每頁的數據量。
  • 對于上述考慮因素,Django 內置的分頁功能已提供解決方法,而且代碼的實現方式相對固定,便于開發者理解和使用。分頁功能由Paginator 類實現,我們在 PyCharm 中查看該類的定義過程

    • Paginator類一共定義了4個初始化參數和8個類方法,每個初始化參數和類方法說明如下:

      • object_list:必選參數,代表需要進行分頁處理的數據,參數值可以為列表、元組或 ORM查詢的數據對象等。
      • per_page:必選參數,設置每一頁的數據量,參數值必須為整型。
      • orphans:可選參數,如果最后一頁的數據量小于或等于參數 orphans 的值,就將最后一頁的數據合并到前一頁的數據。比如有 23 行數據,若參數 pet_page=10、orphans=5,則數據分頁后的總頁數為 2,第一頁顯示 10 行數據,第二頁顯示 13 行數據。
      • allow_empty_first_page:可選參數,是否允許第一頁為空。如果參數值為 False 并且參數
        object_list為空列表,就會引發 EmptyPage 錯誤。
      • validate_number():驗證當前頁數是否大于或等于 1。
      • get_page():調用 validate_number() 驗證當前頁數是否有效,函數返回值調用 page()。
      • page():根據當前頁數對參數 object_list 進行切片處理,獲取頁數所對應的數據信息,畫數道回值調用 _get_page()。
      • _get_page():調用 Page 類,并將當前頁數和頁數所對應的數據信息傳遞給 Page類,創建當前頁數的數據對象。
      • count():獲取參數 object_list的數據長度。
      • num_pages():獲取分頁后的總頁數。
      • page.range():將分頁后的總頁數生成可循環對象。
      • _check_object_list_is_ordered():如果參數 object_list 是 ORM 查詢的數據對象,并且該數據對象的數據是無序排列的,就提示警告信息。
    • 從 Paginator 類定義的 get_page()、page() 和 _get_page() 得知,三者之間存在調用關系,我
      們將它們的調用關系以流程圖的形式表示

  • 我們將 Paginator 類實例化之后,再由實例化對象調用 get_page() 即可得到Page 類的實例化對象。在源碼文件 paginator.py 中可以找到 Page 類的定義過程,它一共定義了3 個初始化參數和 7 個類方法,每個初始化參數和類方法說明如下。

    • object_list:必選參數,代表已切片處理的數據對象。
    • number:必選參數,代表用戶傳遞的頁數。
    • paginator:必選參數,代表 Paginator 類的實例化對象。
    • has_next():判斷當前頁是否存在下一頁。
    • has_previous():判斷當前頁是否存在上一頁。
    • has_other_pages():判斷當前頁是否存在上一頁或者下一頁。
    • next_page_number():如果當前頁存在下一頁,就輸出下一頁的頁數,否則拋出 EmptyPage異常。
    • previous_page_number():如果當前頁存在上一頁,就輸出上一頁的頁數,否則拋出
      EmptyPage 異常。
    • start_index():輸出當前頁的第一行數據在整個數據列表的位置,數據位置從1開始計算。
    • end_index():輸出當前頁的最后一行數據在整個數據列表的位置,數據位置從1開始計算。
  • 上述是從源碼的角度剖析分頁功能的參數和方法,下一步在 PyCharm 的 Terminal中開啟
    Django的 Shell 模式,簡單地講述如何使用分頁功能,代碼如下:

      In [1]: from django.core.paginator import PaginatorIn [2]: # 生成數據列表In [3]: objects = [chr(x) for x in range(97, 107)]In [4]: objectsOut[4]: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']In [5]: # 將數據列表以每3個元素分為1頁In [6]: p = Paginator(objects, 3)In [7]: p.object_listOut[7]: ['a', 'b', 'c', 'd', 'e', 'f', 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92520.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92520.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92520.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

8、STM32每個系列的區別

1、F1和F4的系列的區別 F1采用Crotex M3內核&#xff0c;F4采用Crotex M4內核。F4比F1的主頻高。F4具有浮點數運算單元&#xff0c;F1沒有浮點單元。F4的具備增強的DSP指令集。F407的執行16位DSP指令的時間只有F1的30%~70%。F4執行32位DSP指令的時間只有F1的25% ~ 60%。F1內部S…

DeepSPV:一種從2D超聲圖像中估算3D脾臟體積的深度學習流程|文獻速遞-醫學影像算法文獻分享

Title題目DeepSPV: A deep learning pipeline for 3D spleen volume estimation from 2Dultrasound imagesDeepSPV&#xff1a;一種從2D超聲圖像中估算3D脾臟體積的深度學習流程01文獻速遞介紹1.1 臨床背景 脾腫大指脾臟增大&#xff0c;是多種潛在疾病的重要臨床指標&#x…

病歷數智化3分鐘:AI重構醫院數據價值鏈

一、方案概述本方案針對某省醫聯體醫院病例數據管理需求&#xff0c;通過AI技術實現病歷數字化→信息結構化→數據應用化的全流程改造。系統采用雙端協同架構&#xff1a; - 普通用戶端&#xff1a;為一線醫護人員提供病歷拍攝、AI識別修正、安全上傳功能 - 管理員后臺&#…

CSS+JavaScript 禁用瀏覽器復制功能的幾種方法

&#x1f6e1;? 禁用瀏覽器復制功能完整指南 網頁中禁用用戶的復制功能&#xff0c;包括 CSS 方法、JavaScript 方法、綜合解決方案以及實際應用場景。適用于需要保護內容版權、防止惡意爬取或提升用戶體驗的場景。 &#x1f4cb; 目錄 &#x1f680; 快速開始&#x1f3a8…

Java 虛擬線程在高并發微服務中的實戰經驗分享

Java 虛擬線程在高并發微服務中的實戰經驗分享 虛擬線程&#xff08;Virtual Threads&#xff09;作為Java 19引入的預覽特性&#xff0c;為我們在高并發微服務場景下提供了一種更輕量、易用的并發模型。本文結合真實生產環境&#xff0c;講述在Spring Boot微服務中引入和使用虛…

《拆解WebRTC:NAT穿透的探測邏輯與中繼方案》

WebRTC以其無需插件的便捷性&#xff0c;成為連接全球用戶的隱形橋梁。但很少有人知曉&#xff0c;每一次流暢的視頻對話背后&#xff0c;都藏著一場與網絡邊界的無聲博弈——NAT&#xff0c;這個為緩解IPv4地址枯竭而生的技術&#xff0c;既是網絡安全的屏障&#xff0c;也是端…

前端開發 React 組件優化

1. 使用 React.memo 進行組件優化問題&#xff1a;當父組件重新渲染時&#xff0c;子組件也會重新渲染&#xff0c;即使它的 props 沒有變化。解決方案&#xff1a;使用 React.memo 包裹子組件&#xff0c;讓其只在 props 變化時才重新渲染。示例場景&#xff1a;展示一個顯示計…

變頻器實習DAY12

目錄變頻器實習DAY12一、繼續&#xff0c;柔性平臺測試&#xff01;上午 王工Modbus新功能測試下午 柔性平臺繼續按照說明書再測一遍附加的小知識點中國貍花貓.git文件附學習參考網址歡迎大家有問題評論交流 (* ^ ω ^)變頻器實習DAY12 一、繼續&#xff0c;柔性平臺測試&…

Redis--多路復用

&#x1f9e9; 一、什么是“客戶端連接”&#xff1f;所謂 客戶端連接 Redis&#xff0c;指的是&#xff1a;一個程序&#xff08;客戶端&#xff09;通過網絡連接到 Redis 服務端&#xff08;比如 127.0.0.1:6379&#xff09;&#xff0c;建立一個 TCP 連接&#xff0c;雙方可…

數組——初識數據結構

一維數組數組的創建數組是一種相同類型元素的集合數組的創建方式C99 中引入了變長數組的概念&#xff0c;變長數組支持數組的大小使用變量來指定明顯這里的vs2019不支持變長數組數組初始化和不完全初始化第二個數組就是典型的不完全初始化&#xff0c;開辟了10個空間&#xff0…

技術速遞|使用 Semantic Kernel 與 A2A 協議構建多智能體解決方案

作者&#xff1a;盧建暉 - 微軟高級云技術布道師 翻譯/排版&#xff1a;Alan Wang 在快速發展的 AI 應用開發領域&#xff0c;能夠協調多個智能體已成為構建復雜企業級解決方案的關鍵。雖然單個 AI 智能體擅長特定任務&#xff0c;但復雜的業務場景往往需要跨平臺、跨框架甚至跨…

前端跨域請求原理及實踐

在前端開發中&#xff0c;"跨域"是一個繞不開的話題。當我們的頁面嘗試從一個域名請求另一個域名的資源時&#xff0c;瀏覽器往往會拋出類似Access to fetch at xxx from origin xxx has been blocked by CORS policy的錯誤。下面將深入探討跨域請求的底層原理&#…

SpringBoot07-數據層的解決方案:SQL

一、內置數據源 1-1、【回顧】Druid數據源的配置 druid的兩種導入格式 1-2、springboot提供的3種內置數據源的配置 若是不配置Druid&#xff0c; springboot提供了3中默認的數據源配置&#xff0c;它們分別是&#xff1a; 1. HikariCP&#xff08;默認&#xff09; 從 Spring…

前端自動化埋點:頁面模塊級行為跟蹤與問題定位系統??的技術設計方案

一、核心設計目標??精細化監控??&#xff1a;定位到頁面中??單個模塊??的曝光、點擊等行為。??低侵入性??&#xff1a;業務代碼與埋點邏輯解耦&#xff0c;降低開發維護成本。??鏈路可追蹤??&#xff1a;串聯用戶從曝光到操作的完整行為路徑。??實時性??&a…

Node.js 與 Java 性能對比

一、核心架構與任務模型對比Node.js 單線程事件循環 非阻塞I/O 通過V8引擎執行JavaScript&#xff0c;采用事件驅動模型&#xff0c;所有I/O操作&#xff08;如網絡請求、文件讀寫&#xff09;均為非阻塞。單線程處理所有請求&#xff0c;但通過事件循環&#xff08;Event Loo…

Python3常見接口函數

Python3常見接口函數一、基礎內置函數 輸入輸出 print()&#xff1a;輸出內容input()&#xff1a;讀取用戶輸入 類型轉換 int()、float()、str()、bool()&#xff1a;基礎類型轉換list()、tuple()、set()、dict()&#xff1a;容器類型轉換bin()、hex()、oct()&#xff1a;進制轉…

《P4092 [HEOI2016/TJOI2016] 樹》

題目描述在 2016 年&#xff0c;佳媛姐姐剛剛學習了樹&#xff0c;非常開心。現在他想解決這樣一個問題&#xff1a;給定一顆有根樹&#xff0c;根為 1 &#xff0c;有以下兩種操作&#xff1a;標記操作&#xff1a;對某個結點打上標記。&#xff08;在最開始&#xff0c;只有結…

TCP頭部

TCP頭部字段詳解1. 源端口和目的端口&#xff08;各16位&#xff09;功能&#xff1a;標識發送和接收應用程序范圍&#xff1a;0-65535&#xff08;0-1023為知名端口&#xff09;技術細節&#xff1a;客戶端通常使用臨時端口&#xff08;1024-65535&#xff09;服務端使用固定端…

LinkedList與鏈表(單向)(Java實現)

引入鏈表結構&#xff1a;在ArrayList任意位置插入或者刪除元素時&#xff0c;就需要將后序元素整體往前或者往后 搬移&#xff0c;時間復雜度為O(n)&#xff0c;效率比較低&#xff0c;因此ArrayList不適合做任意位置插入和刪除比較多的場景。因此&#xff1a;java集合中又引入…

網絡--VLAN技術

目錄 VLAN實驗報告 一、實驗拓撲 二、實驗要求 三、實驗思路 1、實驗準備 2. VLAN 3. DHCP 自動分配 4、 全網可達驗證 四、實驗步驟 &#xff08;一&#xff09;交換機配置- VLAN 創建與接口劃分 &#xff08;二&#xff09;路由器配置&#xff08;R1&#xff0c…