Django商城项目笔记No.18商品部分-数据表创建
数据库表设计
在电商中对于商品,有两个重要的概念:SPU和SKU
SPU = Standard Product Unit (标准产品单位)
SPU是商品信息聚合的最小单位,是一组可服用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
通俗的讲,属性值、特性相同的商品就可以称为一个SPU。
例如:
iPhone X 就是一个SPU,与商家、颜色、款式、规格、套餐等都无关。
SKU = Stock Keeping Unit (库存量单位)
SKU即库存进出计量的单位,可以是以件、盒、托盘等为单位,是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。在服装、鞋类商品中使用最多最普遍。
例如:
iPhone X 全网通黑色256G 就是一个SKU,表示了具体的规格、颜色等信息。
总结:
SPU是某一类商品
SKU是某一件商品
商品数据表结构
首页广告数据表结构
数据库模型类
创建商品应用goods,商品数据模型类
- python ../../manage.py startapp goods
- class GoodsCategory(BaseModel):
- """
- 商品类别
- """
- name = models.CharField(max_length=10, verbose_name='名称')
- parent = models.ForeignKey('self', 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 GoodsChannel(BaseModel):
- """
- 商品频道
- """
- group_id = models.IntegerField(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 Goods(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_goods', verbose_name='一级类别')
- category2 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat2_goods', verbose_name='二级类别')
- category3 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat3_goods', verbose_name='三级类别')
- sales = models.IntegerField(default=0, verbose_name='销量')
- comments = models.IntegerField(default=0, verbose_name='评价数')
- class Meta:
- db_table = 'tb_goods'
- verbose_name = '商品'
- verbose_name_plural = verbose_name
- def __str__(self):
- return self.name
- class GoodsSpecification(BaseModel):
- """
- 商品规格
- """
- goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品')
- name = models.CharField(max_length=20, verbose_name='规格名称')
- class Meta:
- db_table = 'tb_goods_specification'
- verbose_name = '商品规格'
- verbose_name_plural = verbose_name
- def __str__(self):
- return '%s: %s' % (self.goods.name, self.name)
- class SpecificationOption(BaseModel):
- """
- 规格选项
- """
- spec = models.ForeignKey(GoodsSpecification, 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 SKU(BaseModel):
- """
- 商品SKU
- """
- name = models.CharField(max_length=50, verbose_name='名称')
- caption = models.CharField(max_length=100, verbose_name='副标题')
- goods = models.ForeignKey(Goods, 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.CharField(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 SKUSpecification(BaseModel):
- """
- SKU具体规格
- """
- sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku')
- spec = models.ForeignKey(GoodsSpecification, 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)
创建广告内容应用contents,广告数据模型类
- python ../../manage.py startapp contents
- 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
执行数据库迁移
- python manage.py makemigrations
- python manage.py migrate
Django商城项目笔记No.18商品部分-数据表创建的更多相关文章
- Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid
Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid 上一步获取QQ登录网址之后,测试登录之后本该跳转到这个界面 但是报错了: 新建oauth_callback.html & ...
- Django商城项目笔记No.10用户部分-登录接口
Django商城项目笔记No.10用户部分-登录接口 添加url路由 接下来第二步,增加返回内容: 增加结果如下: 配置:上边的方法定义了返回的内容都有哪些,那这个方法jwt还不知道,需要配置: 修改 ...
- Django商城项目笔记No.5用户部分-注册接口-短信验证码
Django商城项目笔记No.4用户部分-注册接口-短信验证码 短信验证码也保存在redis里(sms_code_15101234567) 在views中新增SMSCodeView类视图,并且写出步骤 ...
- Django商城项目笔记No.11用户部分-QQ登录1获取QQ登录网址
Django商城项目笔记No.11用户部分-QQ登录 QQ登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 若想实现QQ登录,需要成为QQ互联 ...
- Django商城项目笔记No.9用户部分-注册接口签发JWTtoken
Django商城项目笔记No.9用户部分-注册接口签发JWTtoken 我们在验证完用户的身份后(检验用户名和密码),需要向用户签发JWT,在需要用到用户身份信息的时候,还需核验用户的JWT. 关于签 ...
- Django商城项目笔记No.8用户部分-注册接口实现
Django商城项目笔记No.8用户部分-注册接口实现 users的view.py中增加如下代码 class RegisterUserView(CreateAPIView): "" ...
- Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在
Django商城项目笔记No.7用户部分-注册接口-判断用户名和手机号是否存在 判断用户名是否存在 后端视图代码实现,在users/view.py里编写如下代码 class UsernameCount ...
- Django商城项目笔记No.6用户部分-注册接口-短信验证码实现celery异步
Django商城项目笔记No.4用户部分-注册接口-短信验证码实现celery异步 接上一篇,如何解决前后端请求跨域问题? 首先想一下,为什么图片验证码请求的也是后端的api.meiduo.site: ...
- Django商城项目笔记No.4用户部分-注册接口-图片验证码
Django商城项目笔记No.4用户部分-注册接口-图片验证码 1.首先分析注册业务接口 1.1.分析可得,至少这么几个接口 图片验证码 短信验证码 用户名是否存在 手机号是否存在 整体注册接口 图片 ...
随机推荐
- U3D Invoke系列函数
public void Invoke(string methodName, float time) 多少秒后执行某个函数 参数说明: methodName:要执行的函数的名称 time:秒数,time ...
- string基本字符序列容器(竞赛时常用的使用方法总结)
C语言只提供了一个char类型用来处理字符,而对于字符串,只能通过字符串数组来处理,而C++STL提供了string基本字符序列容器来处理字符串,可以将其理解为字符串类,它提供了添加,删除,替换.查找 ...
- 传统项目转前端工程化——路由跳转时出现浏览器锁死和白屏【该死的同步ajax】
[一开始我想到是该死的同步ajax,但我没验证,把他忽略了] 在探索前端工程化vue-cli做spa时,从搜索结果页跳转商品详情页时,因为详情页有很多ajax请求,并且都用的同步请求,就会导致请求时浏 ...
- [日常] Go语言圣经--浮点数习题
练习 3.1: 如果f函数返回的是无限制的float64值,那么SVG文件可能输出无效的多边形元素(虽然许多SVG渲染器会妥善处理这类问题).修改程序跳过无效的多边形. 练习 3.2: 试验math包 ...
- Docker的下载与安装
一丶下载 1.win10之外的 Docker下载地址: https://www.docker.com/products/docker-toolbox 2.win10 Docker下载地址: https ...
- 步步深入MySQL:架构->查询执行流程->SQL解析顺序!
一.前言 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序 ...
- Java - fail-fast机制
Java提高篇(三四)-----fail-fast机制 在JDK的Collection中我们时常会看到类似于这样的话: 例如,ArrayList: 注意,迭代器的快速失败行为无法得到保证,因为一般来说 ...
- Java - 线程优先级和守护线程
Java多线程系列--“基础篇”10之 线程优先级和守护线程 概要 本章,会对守护线程和线程优先级进行介绍.涉及到的内容包括:1. 线程优先级的介绍2. 线程优先级的示例3. 守护线程的示例 转载请注 ...
- JS中那些让人头昏眼花的弯子
看别人在讨论,于是整理了下,大家来看看下面代码中1-11分别输出的答案是什么???(不要试过再说) var obj={ a:1, b:2, add:function(c,d){ console.log ...
- linux_shell_数组
shell数组类似与C语言,数组下标由0开始编号.想要获取数组中的元素要利用下标. 1.首先定义数组 在shell中,用括号来表示数组,数组元素用“空格”符号分割开.列: name=("d& ...