【Django开发】前后端分离django美多商城项目第11篇:商品数据库表设计,1. SPU介绍【附代码文档】

news/2024/12/26 8:23:34/

python">本教程的知识点为: 项目准备 项目准备 配置 1. 修改settings/dev.py 文件中的路径信息 2. INSTALLED_APPS 3. 数据库 用户部分 图片 1. 后端接口设计: 视图原型 2. 具体视图实现 用户部分 使用Celery完成发送 判断帐号是否存在 1. 判断用户名是否存在 后端接口设计: 用户部分 JWT 什么是JWT 起源 传统的session认证 用户部分 登录 1. 业务说明 2. 后端接口设计 3. 后端实现 登录 使用登录的流程 创建模型类 urllib使用说明 登录回调处理 登录 使用登录的流程 创建模型类 urllib使用说明 绑定用户身份接口 邮件与验证 学习目标: 业务说明: 技术说明: 保存邮箱并发送验证邮件 省市区地址查询 数据库建表 说明 页面静态化 注意 定时任务 安装 部分 详情页 异步任务的触发 。 后端接口设计 收货地址 使用缓存 安装 使用方法 为省市区视图添加缓存 数据库表设计 表结构 数据表结构 首页数据表结构 Docker使用 Docker简介 用户浏览历史记录 1. 保存 后端接口设计 后端实现 搜索 1. 需求分析 2. 搜索引擎原理 3. Elasticsearch 部分 业务需求分析 技术实现 数据存储设计 1. Redis保存已登录用户 商品部分 业务需求分析 技术实现 查询数据 1. 后端接口设计 部分 业务需求分析 技术实现 登录合并 修改登录视图 部分 保存 1. 后端接口设计 2. 后端实现 保存的思路 创建数据库模型类 接入 开发平台登录 沙箱环境 Xadmin 1. 安装 2. 使用 站点的全局配置 站点Model管理。 在Ubuntu中安装 2. 启动与停止 3. 镜像操作 端与自定义文件存储系统 1. 的Python客户端 安装 使用。

djangodjangonotemd">完整笔记资料代码:https://gitee.com/yinuo112/Backend/tree/master/Django/前后端分离django美多商城项目/note.md

感兴趣的小伙伴可以自取哦~


全套教程部分目录:


部分文件图片:

商品数据库表设计

SPU和SKU

在电商中对于商品,有两个重要的概念:SPUSKU

1. SPU介绍

  • SPU = Standard Product Unit (标准产品单位)
  • SPU是商品信息聚合的最小单位,是一组可服用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
  • 通俗的讲,属性值、特性相同的商品就可以归类到一类SPU。
  • 例如:

    • iPhone X 就是一个SPU,与商家、颜色、款式、规格、套餐等都无关。

2. SKU介绍

  • SKU = Stock Keeping Unit (库存量单位)
  • SKU即库存进出计量的单位,可以是以件、盒等为单位,是物理上不可分割的最小存货单元。
  • 通俗的讲,SKU是指一款商品,每款都有一个SKU,便于电商品牌识别商品。
  • 例如:

    • iPhone X 全网通 黑色 256G 就是一个SKU,表示了具体的规格、颜色等信息。

思考

SPU和SKU是怎样的对应关系?

  • 一对一?
  • 一对多?

首页广告数据库表分析

1. 首页广告数据库表分析

2. 定义首页广告模型类

python linenums">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_namedef __str__(self):return self.nameclass 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_namedef __str__(self):return self.category.name + ': ' + self.title

商品信息数据库表分析

1. 商品信息数据库表分析

2. 定义商品信息模型类

python linenums">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_namedef __str__(self):return self.nameclass GoodsChannelGroup(BaseModel):"""商品频道组"""name = models.CharField(max_length=20, verbose_name='频道组名')class Meta:db_table = 'tb_channel_group'verbose_name = '商品频道组'verbose_name_plural = verbose_namedef __str__(self):return self.nameclass GoodsChannel(BaseModel):"""商品频道"""group = models.ForeignKey(GoodsChannelGroup, 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_namedef __str__(self):return self.category.nameclass 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_namedef __str__(self):return self.nameclass 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_namedef __str__(self):return self.nameclass 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.CharField(max_length=200, default='', null=True, blank=True, verbose_name='默认图片')class Meta:db_table = 'tb_sku'verbose_name = '商品SKU'verbose_name_plural = verbose_namedef __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_namedef __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_namedef __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_namedef __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_namedef __str__(self):return '%s: %s - %s' % (self.sku, self.spec.name, self.option.value)

准备商品数据

提示:

  • 数据库表有了以后,我们现在需要准备商品信息数据和商品图片数据,以便查询和展示。
  • 商品信息数据:比如商品编号等都是字符串类型的,可以直接存储在MySQL数据库。
  • 商品图片数据:MySQL通常存储的是图片的地址字符串信息。

  • 所以图片数据需要进行其他的物理存储。

图片物理存储思考:

  • 需要提供图片上传和下载的机制。
  • 需要解决图片备份和扩容的问题。
  • 需要解决图片重名的问题等等。

图片物理存储方案:

  • FastDFS

文件存储方案FastDFS

1. FastDFS介绍

  • c语言编写的一款开源的轻量级分布式文件系统。
  • 功能包括:文件存储、文件访问(文件上传、文件下载)、文件同步等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
  • 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标。
  • 可以帮助我们搭建一套高性能的文件服务器集群,并提供文件上传、下载等服务。

  • FastDFS架构 包括ClientTracker serverStorage server

  • Client请求Tracker进行文件上传、下载,Tracker再调度Storage完成文件上传和下载。

  • Client: 客户端,业务请求的发起方,通过专有接口,使用TCP/IP协议与TrackerStorage进行数据交互。FastDFS提供了uploaddownloaddelete等接口供客户端使用。

  • Tracker server:跟踪服务器,主要做调度工作,起负载均衡的作用。在内存中记录集群中所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽。
  • Storage server:存储服务器(存储节点或数据服务器),文件和文件属性都保存到存储服务器上。Storage server直接利用OS的文件系统调用管理文件。

  • Storage群中的横向可以扩容,纵向可以备份

2. FastDFS上传和下载流程

3. FastDFS文件索引

  • FastDFS上传和下载流程 可以看出都涉及到一个数据叫文件索引(file_id)

  • 文件索引(file_id)是客户端上传文件后Storage返回给客户端的一个字符串,是以后访问该文件的索引信息。

  • 文件索引(file_id)信息包括:组名、虚拟磁盘路径、数据两级目录、文件名等信息。

  • 组名:文件上传后所在的 Storage 组名称。

  • 虚拟磁盘路径:Storage 配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。
  • 数据两级目录:Storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
  • 文件名:由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。


http://www.ppmy.cn/news/1557842.html

相关文章

分布式爬虫scrapy-redis

Scrapy 爬虫,虽然爬虫是异步加多线程的,但是我们只能在一台主机上运行,所以爬取效率还是有限的,分布式爬虫则是将多台主机组合起来,共同完成一个爬取任务,这将大大提高爬取的效率。 分布式爬虫解决的问题1:爬虫任务共享 所谓分布式爬虫,我们需要做的就是在多台主机上…

Day1 苍穹外卖前端 Vue基础、Vue基本使用方式、Vue-router、Vuex、TypeScript

目录 1.VUE 基础回顾 1.1 基于脚手架创建前端工程 1.1.1 环境要求 1.1.2 脚手架创建项目 1.1.3 工程结构 1.1.4 启动前端服务 1.2 vue基本使用方式 1.2.1 vue 组件 1.2.2 文本插值 1.2.3 属性绑定 1.2.4 事件绑定 1.2.5 双向绑定 1.2.6 条件渲染 1.2.7 跨域问题 1.2.8 axios 1.…

Excel中match()函数

函数功能概述 MATCH 函数是 Excel 中用于在指定区域中查找特定值的位置的函数。它返回指定数值在指定数组区域中的位置。这个位置是相对于查找区域的相对位置,而不是绝对的单元格位置。语法结构 MATCH(lookup_value, lookup_array, match_type)lookup_value&#xf…

WebRTC服务质量(08)- 重传机制(05) RTX机制

一、前言: RTX协议(Retransmission,即重传协议)是 WebRTC 中用于处理丢包恢复的一部分。由于网络通信中的丢包不可避免,WebRTC RTP协议栈支持多种丢包恢复机制,其中之一便是通过RTX协议实现的重传机制。 …

Spring Cloud OpenFeign快速入门demo

一、应用场景 Spring Cloud OpenFeign 是一个声明式的 HTTP 客户端,旨在简化微服务之间的通信。它使得开发者能够通过简单的接口定义和注解来调用 RESTful API,极大地减少了样板代码。以下是一些典型的应用场景: 微服务间调用:在…

小程序 - 模拟时钟

微信小程序常用API练习 - 模拟时钟小程序开发笔记 模拟时钟 “模拟时钟”微信小程序是一个简约风格的动态时钟,该时钟时间与系统时间一致,且时针、分针、秒针会与系统时间同步更新,用户可以很方便地查看时间。下面将对“模拟时钟”微信小程序…

【漏洞复现】CVE-2021-45788 SQL Injection

漏洞信息 NVD - cve-2021-45788 Time-based SQL Injection vulnerabilities were found in Metersphere v1.15.4 via the “orders” parameter. Authenticated users can control the parameters in the “order by” statement, which causing SQL injection. API: /test…

MongoDB教程001:基本常用命令(数据库操作和集合操作)

1.1 案例需求 存放文章评论的数据存放到MongoDB中,数据结构参考如下: 数据库:【articledb】 专栏文章评论comment字段名称字段含义字段类型备注_id(MongoDB自动生成)IDObjectId或StringMongo的主键的字段articleId文…