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…