Django项目实践(商城):十七、商品详情页面

在这里插入图片描述

(根据居然老师直播课内容整理)

一、商品详情页分析

在这里插入图片描述

  • 通过页面分析,主要有以下7大功能

1、.商品频道分类

  • 已经提前封装在contents.utils.py文件中,直接调用方法即可

2、面包屑导航

  • 已经提前封装在goods.utils.py文件中,直接调用方法即可。

3、热销排行

  • 该接口已经在商品列表页中实现完毕,前端直接调用接口即可。

4、商品SKU信息(详情信息)

  • 通过sku_id可以找到SKU信息,然后渲染模板即可。
  • 使用Ajax实现局部刷新效果。

5、SKU规格信息

  • 通过SKU可以找到SPU规格和SKU规格信息。

6、商品详情介绍、规格与包装、售后服务

  • 通过SKU可以找到SPU信息,SPU中可以查询出商品详情介绍、规格与包装、售后服务。

7、商品评价

  • 商品评价需要在生成了订单,对订单商品进行评价后再实现,商品评价信息是动态数据。
  • 使用Ajax实现局部刷新效果。

二、商品详情页

  • 点击商品列表页面中某个商品时,会进入商品详情页面

1、商品列表页面完善

  • 商品列表前端页面中跳转页面需要修改
    在这里插入图片描述

2、接口设计与定义

2.1 请求方式

选项 方案
请求方法 GET
请求地址 /detail/(?P<sku_id>\d+)/

2.2 请求参数 : 路径参数 和 查询参数

参数名 类型 是否必传 说明
sku_id string 商品SKU编号

2.3 响应结果 : HTML

detail.html

2.4 接口定义

class DetailView(View):
    """商品详情页"""
    def get(self, request, sku_id):
        """提供商品详情页"""
        return render(request, 'detail.html')

2.5 路由定义

在这里插入图片描述

3、商品详情页初步渲染

3.1 校验参数、渲染商品频道分类、面包屑导航

  • 校验参数
    • 校验sku_id是否存在
  • 渲染商品频道分类、面包屑导航
    • 将原先在商品列表页实现的代码拷贝到商品详情页即可。
    • 面包屑导航原参数是商品分类,可通过SKU的外键category获取category对象
  • html中,商品频道分类、面包屑导航不变,商品详情页面都是该商品的sku信息,将sku传到前端
    def get(self,request,sku_id):
        """提供商品详情页"""
        
        # 校验参数:sku_id
        try: 
            sku=SKU.objects.get(id=sku_id)
        except Exception as e:
            return render(request,"404.html")

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)
        
        content={
   
            'categories': categories,  # 商品频道分类
            'breadcrumb': breadcrumb,  # 面包屑导航
            'sku':sku,                  # 商品sku
        }
            
        return render(request,"detail.html")

3.2 添加商品热销排行

  • 商品热销排行是前端通过Ajax访问
  • 后端实现已封装HotGoodsView()中
  • 修改前端相应模块即可
  • /templates/detail.html
			<div class="new_goods">
				<h3>热销排行</h3>
				<ul>
					<li v-for="sku in hot_skus">
						<a href="{% url 'goods:detail' sku.id %}"><img :src="sku.default_image_url"></a>
						<h4><a href="{% url 'goods:detail' sku.id %}">[[ sku.name ]]</a></h4>
						<div class="price">¥[[ sku.price ]]</div>
					</li>
				</ul>
			</div>
  • /static/js/detail.js
    在这里插入图片描述
    	// 获取热销商品数据
        get_hot_skus(){
   
            if (this.category_id) {
   
                let url = '/hot/'+ this.category_id +'/';
                axios.get(url, {
   
                    responseType: 'json'
                })
                    .then(response => {
   
                        this.hot_skus = response.data.hot_skus;
                        for(let i=0; i<this.hot_skus.length; i++){
   
                            this.hot_skus[i].url = '/detail/' + this.hot_skus[i].id + '/';
                        }
                    })
                    .catch(error => {
   
                        console.log(error.response);
                    })
            }
        },

  • 为了让前端在获取商品热销排行数据时,能够拿到商品分类ID,我们将商品分类ID从模板传入到Vue.js
    在这里插入图片描述
    在这里插入图片描述

3.3 修改名称、标题、单价

在这里插入图片描述

3.4 修改总价

  • 总价通过vue计算得到
  • data中定义sku_amount
  • 通过监听商品数量量变化,计算总价
  • 需要接收后端传递的参数,获取单价
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、查询SKU规格信息后端实现

  • 不同商品的规格名称和规格信息可能不同, 即不同商品SPU的规格名称和规格选详不同
    • 如衣服规格名称可能有:尺寸编码、颜色、款式等,尺寸编码信息可能有 S、M、L、XL、XXL、XXXL等
    • 手机规格名称 可能有:屏幕大小、颜色等,屏幕大小信息可能:5.5 、6.3 等
  • 同一商品SPU中,不同规格之间,SKU也可能不同
    • 同一款手机spu_id=2 : 规格名称和信息:内存(64G、256G)、颜色(金色、深空灰色、银色)
    • 选择(64G , 金色) sku_id=3 , 选择 (256G ,金色) sku_id= 4 …
      在这里插入图片描述
  • 进入详情页面时,SKU_id已明确,需要在规格选项中确定其默认值
  • 当选择其它规格选项时,sku_id可能发生变化

4.1 获取当前商品的默认规格选项列表

        # 构建当前商品的规格信息id的列表  当前sku id为3的默认的规格
        sku_specs = SKUSpecification.objects.filter(sku__id=sku_id).order_by('spec_id')
        print("sku_specs.query=",sku_specs.query)
        # sku_specs.query= SELECT `tb_sku_specification`.`id`, `tb_sku_specification`.`create_time`, `tb_sku_specification`.`update_time`, `tb_sku_specification`.`sku_id`, `tb_sku_specification`.`spec_id`, `tb_sku_specification`.`option_id` FROM `tb_sku_specification` WHERE `tb_sku_specification`.`sku_id` = 1 ORDER BY `tb_sku_specification`.`spec_id` ASC
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # sku_id=3 时  sku_key= [8, 11]

4.2 构建当前商品SPU下不同规格参数(选项)的sku字典

  • 获取当前sku_id的商品SPU的 id :spu_id
  • 查询id = sup_id 的所有SKU商品集
  • 循环取出SKU商品集
    • 根据商品sku 取出 SKU规格集
    • 将该sku商品的所有规格id组成列表
    • 将此列表转换成元组,做为spec_sku_map字典的key,把该商品sku_id作为value
  • 当前sku_id的商品SPU相同的一个字典,该字典对应关系是 sku规格集 : sku_id
    • 目的是选择不同的商品规格组合时,可以确定该规格对应的sku_id
        # 获取当前商品的所有SKU
        spu_id = sku.spu_id
        skus = SKU.objects.filter(spu_id=spu_id)

        # 构建不同规格参数(选项)的sku字典
        spec_sku_map = {
   }
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')

            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id

		# spec_sku_map= {(8, 11): 3, (8, 12): 4, (9, 11): 5, (9, 12): 6, (10, 11): 7, (10, 12): 8}

4.3 为前端渲染提供数据

  • 获取当前商品SPU规格名称集goods_specs
  • 对SPU规格名称集goods_specs进行循环
    • 对过enumerate()对数据集进行编号
    • 将sku_key的值,赋值给key
    • 取出该SPU的规格信息集spec_options
    • 循环遍历规格信息集spec_options
      • 将规格替换 key[当前编号]的值
      • 给当格信息集spec_options中当前对象添加sku_id属性,并将获取SPU下不同规格参数(选项)的sku字典中对的sku_id
    • 将 spec_options对象添加为规格名称集goods_specs的spec_options属性
        # 获取当前商
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值