Django项目实践(商城):十二、商品信息数据库设计

在这里插入图片描述

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

一、SPU和SKU

  • 在电商中对于商品,有两个重要的概念:SPU和SKU

1、SPU介绍

  • SPU,是standard product unit,标准化产品单元,是商品信息聚合的最小单位,是一组可服用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
  • 通俗的讲,属性值、特性相同的商品就可以归类到一类SPU。(在淘宝看不到spu这个概念,淘宝商品都拥有商品ID(item design),相当于spu)
  • 例如: iPhone X 就是一个SPU,与商家、颜色、款式、规格、套餐等都无关。
  • SPU是用来定位的,京东前台看不到单品的spu是多少,想查看只能到店铺后台中查看,淘宝是可以在前台链接中看到该商品的ID的,比如:
    • 这是天猫的一款产品点击主图后进入的页面,最后是id=544576894375,这个是商品的id,在出售中的宝贝中也可以看到:
      在这里插入图片描述
    • 而京东的spu就需要到京东后台查看

2、SKU介绍

  • SKU是stock keeping unit(库存量单位),库存进出计量的单位,用来定价和管理库存的,可以是以件、盒等为单位,是物理上不可分割的最小存货单元。

  • 通俗的讲,SKU是指一款商品,每款都有一个SKU,便于电商品牌识别商品。

  • 例如:7Plus有很多颜色,很多配置,每个颜色和配置的组合都会形成新的产品,这时就产生很多SKU

  • SKU在传统线下行业也是一个非常常用的概念,尤其是服装行业,同款不同尺码不同色都是独立的
    SKU,需要有独立的条形码,独立的库存管理等。

  • 在京东,所有的商品在前台都是看不到spu值的,链接中都是直接显示SKU。

  • 在淘宝,可以从链接中看出ID和sku两个值。

  • 刚才我们举例的这个商品,这个商品其实是有多个颜色的,接下来我们选择其中的一个颜色,比如青色:
    在这里插入图片描述

  • 选择后,我们发现顶部的链接发生的变化,&id=544576894375&skuId=3281815068747刚才的id后,又出现了skuId。
    在这里插入图片描述

  • 总结:iPhone 7 Plus就是一个独立的SPU,爱普生6721墨水也是一个SPU,至于7 plus还有各种颜色,各种配置,墨水有多种颜色,那都是SKU的事情了。统计销售数据,我们通常用到的是spu,比如我想知道7plus卖了多少台,我通过spu来查看;但分析客户和市场,通常用sku更多,比如我想看7plus哪个颜色和配置更受买家欢迎,肯定要用的SKU。

  • 以上内容还参考以下内容

二、首页广告数据库表分析

在这里插入图片描述

  • 首页不同的区域,广告形式也不同
  • 如: 轮播图区,循环不同的广告内容,一级广告区:播广一些竞价高的广告,二级广告区:播放一些次一级广告,还有些广告,属于见缝插针类形,总之根据需求,需要把广分成不同类型,同一类型的广告,也有需要先后顺序
  • url:每个广告图片及文件都会对应一个特定的页面
  • image:广告图片地址
  • text:文字广告词
  • sequence、status:是能后台管理用的,并且控制广显示

1、首页广告模型类定义

#  /apps/content/models.py 
from django.db import models
from utils.models import BaseModel

class ContentCategory(BaseModel):
    """广告内容类别"""
    name = models.CharField(max_length=50, verbose_name='名称')
    key = models.CharField(max_length=50, verbose_name='类别键名')

    class Meta:
        db_table = 'tb_content_category'
        verbose_name = '广告内容类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Content(BaseModel):
    """广告内容"""
    category = models.ForeignKey(ContentCategory, on_delete=models.PROTECT, verbose_name='类别')
    title = models.CharField(max_length=100, verbose_name='标题')
    url = models.CharField(max_length=300, verbose_name='内容链接')
    image = models.ImageField(null=True, blank=True, verbose_name='图片')
    text = models.TextField(null=True, blank=True, verbose_name='内容')
    sequence = models.IntegerField(verbose_name='排序')
    status = models.BooleanField(default=True, verbose_name='是否展示')

    class Meta:
        db_table = 'tb_content'
        verbose_name = '广告内容'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.category.name + ': ' + self.title

三、商品信息数据库表分析

在这里插入图片描述

1、商品类别、商品频道、商品频道组

在这里插入图片描述

1.1 商品类别表

在这里插入图片描述

  • 这是一个多层级的商品类别自关联表
  • 第一级商品类别的parent(父类别)为空
  • 第二级商品类别的parent(父类别)为一级商品类别的id
  • 依此类推…

1.2 商品频道表

在这里插入图片描述

  • 这个表与商品类别表是一对一的关系,与商品类别表中一级商品类别一一对应,即一级商品类别就是商品频道,下辖二级商商品类别,二级商品类别下辖三级商品类别
  • 每个商品频道都对应一个频道链接页面,展示该商品频道(类别)下的二级商品类别、三级商品类别及商品明细等
  • 每一个商品频道还包含一个在商品频道组内的顺序号,用于同一组商品频道显示时的先后顺序

1.3 商品频道组表

在这里插入图片描述

  • 这个表与商品频道表是一对多的关系
  • 用于将商品频道进行分组,方便数据展示

1.4 商品频道组、商品频道、商品类别 常见应用

在这里插入图片描述

2、商品品牌 和 商品SPU

在这里插入图片描述

  • 商品品牌表 和 商品SPU表 是一对多的关系

2.1 商品品牌表

  • 在这里插入图片描述
  • 品牌有logo图片和检索字段等,故将其从SPU里独立出来
  • 品牌logo图片只保存图片链接
  • 品牌首字母用于品牌检索

2.2 商品(SPU)

在这里插入图片描述

  • 每一个商品(SPU)保存着一级、二级、三级类别id ,以便对应检索
  • 每一个商品(SPU)都保存该商品SPU的销量和评论量、详细介绍、包装信息、售后服务

3、商品SKU 和 SKU图片

3.1 商品SKU

在这里插入图片描述

  • 每个商品SPU与SKU是一对多的关系
  • 每一个具体的商品SKU都有三级类别id,根据商品类别展示商品时,会按商品SPU展示,所以未保存一、二级商品类别,如果需要,可以通过三级类别找到一二级类别,或通过SPU来找
  • 每一个具体的商品都有单价、进价、市场价、库存、销量、评论量、默认图片(保存图片地址)、是否上架
  • 具体商品SKU的图片不止一张,所以单独存放
  • 具体商品SKU的其它同一类SPU共用信息,通过关联表集中保存
  • 3.2 SKU图片

在这里插入图片描述

  • 保存图片的地址

4、SPU规格、规格选项

4.1 SPU规格

在这里插入图片描述

  • 不同的SPU规格类型不同
  • 如:衣服分尺码、颜色 ;手机分机身颜色、套餐类型、存贮容量、基本类型等

4.2 规格选项

在这里插入图片描述

  • 每一个SPU规格名称,都有对应的选项

4.3 SPU规格与规格选项对应关系

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

5、SKU规格

在这里插入图片描述

在这里插入图片描述

  • 这是一个中间表,关联SKU、SPU规格、规格选项
  • 如: 某件具体的衣服SKU规格有2个条记录:1,尺码、28;1,颜色,黑
  •   刚买的一款手机SKU规格有4条记录:2,机身颜色,镜黑;2,套餐类型,官方标准;2,存储容量,12+256GB;2,版本类型,中国大陆
    

四、商品信息模型类定义

  • 商品信息应单独建一个app应用,存储相关应用

1、建立一个app应用

1.1 创建app应用

在这里插入图片描述

1.2 注册app

  • #/lgshop/dev.py在这里插入图片描述

2、商品信息模型类

# /apps/goods/models.py 

from django.db import models
from utils.models import BaseModel

# Create your models here.
class GoodsCategory(BaseModel):
    """商品类别"""
    name = models.CharField(max_length=10, verbose_name='名称')
    parent = models.ForeignKey('self', related_name='subs', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父类别')

    class Meta:
        db_table = 'tb_goods_category'
        verbose_name = '商品类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class GoodsChannelGroup(BaseModel):
    """商品频道组"""
    name = models.CharField(max_length=20, verbose_name='频道组名')

    class Meta:
        db_table = 'tb_channel_group'
        verbose_name = '商品频道组'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class GoodsChannel(BaseModel):
    """商品频道"""
    group = models.ForeignKey(GoodsChannelGroup, on_delete=models.CASCADE, verbose_name='频道组名')
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='顶级商品类别')
    url = models.CharField(max_length=50, verbose_name='频道页面链接')
    sequence = models.IntegerField(verbose_name='组内顺序')

    class Meta:
        db_table = 'tb_goods_channel'
        verbose_name = '商品频道'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.category.name


class Brand(BaseModel):
    """品牌"""
    name = models.CharField(max_length=20, verbose_name='名称')
    logo = models.ImageField(verbose_name='Logo图片')
    first_letter = models.CharField(max_length=1, verbose_name='品牌首字母')

    class Meta:
        db_table = 'tb_brand'
        verbose_name = '品牌'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class SPU(BaseModel):
    """商品SPU"""
    name = models.CharField(max_length=50, verbose_name='名称')
    brand = models.ForeignKey(Brand, on_delete=models.PROTECT, verbose_name='品牌')
    category1 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat1_spu', verbose_name='一级类别')
    category2 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat2_spu', verbose_name='二级类别')
    category3 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat3_spu', verbose_name='三级类别')
    sales = models.IntegerField(default=0, verbose_name='销量')
    comments = models.IntegerField(default=0, verbose_name='评价数')
    desc_detail = models.TextField(default='', verbose_name='详细介绍')
    desc_pack = models.TextField(default='', verbose_name='包装信息')
    desc_service = models.TextField(default='', verbose_name='售后服务')

    class Meta:
        db_table = 'tb_spu'
        verbose_name = '商品SPU'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class SKU(BaseModel):
    """商品SKU"""
    name = models.CharField(max_length=50, verbose_name='名称')
    caption = models.CharField(max_length=100, verbose_name='副标题')
    spu = models.ForeignKey(SPU, on_delete=models.CASCADE, verbose_name='商品')
    category = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, verbose_name='从属类别')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='单价')
    cost_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='进价')
    market_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='市场价')
    stock = models.IntegerField(default=0, verbose_name='库存')
    sales = models.IntegerField(default=0, verbose_name='销量')
    comments = models.IntegerField(default=0, verbose_name='评价数')
    is_launched = models.BooleanField(default=True, verbose_name='是否上架销售')
    default_image_url = models.ImageField(max_length=200, default='', null=True, blank=True, verbose_name='默认图片')

    class Meta:
        db_table = 'tb_sku'
        verbose_name = '商品SKU'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.id, self.name)


class SKUImage(BaseModel):
    """SKU图片"""
    sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku')
    image = models.ImageField(verbose_name='图片')

    class Meta:
        db_table = 'tb_sku_image'
        verbose_name = 'SKU图片'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s %s' % (self.sku.name, self.id)


class SPUSpecification(BaseModel):
    """商品SPU规格"""
    spu = models.ForeignKey(SPU, on_delete=models.CASCADE, related_name='specs', verbose_name='商品SPU')
    name = models.CharField(max_length=20, verbose_name='规格名称')

    class Meta:
        db_table = 'tb_spu_specification'
        verbose_name = '商品SPU规格'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.spu.name, self.name)


class SpecificationOption(BaseModel):
    """规格选项"""
    spec = models.ForeignKey(SPUSpecification, related_name='options', on_delete=models.CASCADE, verbose_name='规格')
    value = models.CharField(max_length=20, verbose_name='选项值')

    class Meta:
        db_table = 'tb_specification_option'
        verbose_name = '规格选项'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s - %s' % (self.spec, self.value)


class SKUSpecification(BaseModel):
    """SKU具体规格"""
    sku = models.ForeignKey(SKU, related_name='specs', on_delete=models.CASCADE, verbose_name='sku')
    spec = models.ForeignKey(SPUSpecification, on_delete=models.PROTECT, verbose_name='规格名称')
    option = models.ForeignKey(SpecificationOption, on_delete=models.PROTECT, verbose_name='规格值')

    class Meta:
        db_table = 'tb_sku_specification'
        verbose_name = 'SKU规格'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s - %s' % (self.sku, self.spec.name, self.option.value)

猜你喜欢

转载自blog.csdn.net/laoluobo76/article/details/114974119
今日推荐