### 5.5商品
#### 1.SPU和SKU
1. SPU介绍 商品统称(类)
SPU = Standard Product Unit (标准产品单位)
- SPU是商品信息聚合的最小单位,是一组可服用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
- 通俗的讲,属性值、特性相同的商品就可以归类到一类SPU。
- 例如:
- `iPhone X` 就是一个**SPU**,与商家、颜色、款式、规格、套餐等都无关。
2. SKU介绍 商品具体化(对象)
SKU = Stock Keeping Unit (库存量单位)
- SKU即库存进出计量的单位,可以是以件、盒等为单位,是物理上不可分割的最小存货单元。
- 通俗的讲,SKU是指一款商品,每款都有一个SKU,便于电商品牌识别商品。
- 例如:
- `iPhone X 全网通 黑色 256G` 就是一个**SKU**,表示了具体的规格、颜色等信息。
#### 2.首页广告模型类
首先商品分为2个部分 一个部分为首页的广告,另一个部分储存所有的商品数据
1. 首页广告数据库分析
![1559219216983](assets/1559219216983.png)
1. 广告类别表用于上部分类栏的显示 如图:
![1559219843537](assets/1559219843537.png)
2. 广告内容表用于存放所有会在首页展示出来的表
模型的建立
```python
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
```
#### 3.商品信息模型类
![1559221758474](assets/1559221758474.png)
- 商品类别表是一个自关联的三级表 类似地区
- 表
- 表一 :定义一个商品的SUP---苹果8---id为1
- 表三:储存了该商品的规格
| spu | 规格 |
| ---- | ------- |
| 1 | 颜色--1 |
| 1 | 配置--2 |
- 表五:定义了该规格的具体配置选项
设颜色有黑色和蓝色 配置有64和128
| 规格 | 选项 |
| ---- | ---- |
| 1 | 蓝色 |
| 1 | 黑色 |
| 2 | 64 |
| 2 | 128 |
总陈列数=规格1的选项数*规格2的选项数
- 每一个具体的选项写在一行中,这样方便日后的扩展
- 表二:SKU 具体商品信息表
该表只存放商品的具体参数,不存放规格信息
此时根据配置,一共有4种商品 每个商品的每个规格存放一行
| SKU的ID | 规格的ID | 选项的ID |
| --------------------- | -------- | -------- |
| 1--荣耀10 (黑+4+64) | 1--颜色 | 1--黑 |
| 1--荣耀10 (黑+4+64) | 2--配置 | 3--4+64 |
| 2--荣耀10 (蓝+4+64) | 1--颜色 | 2--蓝 |
| 2--荣耀10 (蓝+4+64) | 2--配置 | 3--4+64 |
| 3 | 1 | 1 |
| 3 | 2 | 4 |
| 4 | 1 | 2 |
| 4 | 2 | 4 |
这样设计的原因 就是为了后期的扩展方便
#### 4.容器化方案Docker
##### 概述
- [Docker中文社区文档](http://www.docker.org.cn/index.html)
- Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让我们的应用程序具备可移植性、易于构建、并易于协作。
- Docker 是一个开源的软件部署解决方案。
- Docker 也是轻量级的应用容器框架。
- Docker 可以打包、发布、运行任何的应用。
- Docker 就像一个盒子,里面可以装很多物件,如果需要某些物件,可以直接将该盒子拿走,而不需要从该盒子中一件一件的取。
- Docker 是一个客户端-服务端(C/S)
架构程序。
- 客户端只需要向服务端发出请求,服务端处理完请求后会返回结果。
**作用:方便将开发阶段的内容打包,直接在服务器上运行**
> Docker 包括三个基本概念:
- 镜像(Image)
- Docker的镜像概念类似于虚拟机里的镜像,是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。
- 例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了MySQL或用户需要的其它应用程序。
- 容器(Container)
- Docker容器是由Docker镜像创建的运行实例,类似VM虚拟机,支持启动,停止,删除等。
- 每个容器间是相互隔离的,容器中会运行特定的应用,包含特定应用的代码及所需的依赖文件。
- [仓库(Repository)](https://hub.docker.com/)
- Docker的仓库功能类似于Github,是用于托管镜像的
2. ##### Docker安装
> **1.源码安装Docker CE**
```bash
$ cd docker源码目录
$ sudo apt-key add gpg
$ sudo dpkg -i docker-ce_17.03.2~ce-0~ubuntu-xenial_amd64.deb
```
#### 5.Docker的安装
##### 命令
1. ###### 固定语法
镜像:
- sudo docker image....固定前缀
容器:
- sudo docker container...固定前缀
2. ###### 查看当前所以镜像
sudo docker image ls
3. ###### 从仓库拉取镜像
```bash
# 官方镜像
$ sudo docker image pull 镜像名称 或者 sudo docker image pull library/镜像名称
$ sudo docker image pull ubuntu 或者 sudo docker image pull library/ubuntu
$ sudo docker image pull ubuntu:16.04 或者 sudo docker image pull library/ubuntu:16.04
# 个人镜像 需要当前目录为仓库目录 否则需要加路径
$ sudo docker image pull 仓库名称/镜像名称
$ sudo docker image pull itcast/fastdfs
```
4. ###### 删除镜像
```bash
$ sudo docker image rm 镜像名或镜像ID
$ sudo docker image rm hello-world
$ sudo docker image rm fce289e99eb9
```
- 运行镜像,将镜像中的软件跑起来,可以创建出来一个容器
5. ###### 容器列表
```bash
# 查看正在运行的容器
$ sudo docker container ls
# 查看所有的容器
$ sudo docker container ls --all(-a亦可)
```
#### 6.FastDFS
作用:保存文件,实现文件服务器与代码服务器分离
![1559231851858](../../%E7%AC%94%E8%AE%B0/%E5%8D%95%E6%97%A5%E7%AC%94%E8%AE%B0django/assets/1559231851858.png)
- 如图 client可以看做Django服务器,tarcker用于追踪,storage用于储存
- tarcker和storage是fastDFS的组成部分
- 工作原理:storage会向tracker发消息,则tracker维护可用storage列表(实时发送),Django收到一个文件,与tarcker做交互,tarcker与storage交互,在有效列表中查到哪台storage可用于储存,将那台storage的可以用的ip和端口发送给Django,之后Django将与storage联系 ,将文件发送给storage,storage把文件的编号发送给Django
交互流程
- storage会向tracker发消息(实时发送),tracker维护可用storage列表
- 客户端请求tracker,tracker向客户端返回可用的storage
- 客户端请求storage
- storage重新起名,保存文件,返回文件名
- 客户端接收文件名,保存
- 客户端就是我们编写的django程序
**文件保存路径**
![1559234510437](../../%E7%AC%94%E8%AE%B0/%E5%8D%95%E6%97%A5%E7%AC%94%E8%AE%B0django/assets/1559234510437.png)
文件索引(file_id)信息包括:组名、虚拟磁盘路径、数据两级目录、文件名等信息。
- **组名**(group1):文件上传后所在的 Storage 组名称。
- **虚拟磁盘路径**(M00):Storage 配置的虚拟路径,与磁盘选项`store_path*`对应。如果配置了`store_path0`则是`M00`,如果配置了`store_path1`则是`M01`,以此类推。
- **数据两级目录**(00/00):Storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
- **文件名**(后面那一串:由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
- **文件中,组名和虚拟磁盘路径都是不存在的 后面的才是真实存在的位置**
##### 1.Docker安装运行FastDFS
> **1.获取FastDFS镜像**
```bash
# 从仓库拉取镜像
$ sudo docker image pull delron/fastdfs
# 解压本地镜像
$ sudo docker load -i 文件路径/fastdfs_docker.tar
```
解压本地路径,如果在tar文件当前目录运行终端,那么不需要加文件路径/
##### **2.开启tracker容器**
- 我们将 tracker 运行目录映射到宿主机的 `/var/fdfs/tracker`目录中。
这个目录需要手动创建
分配权限:sudo chmod 777 /var/fdfs 有这个权限才能写入数据
```bash
$ sudo docker run -dit --name tracker --network=host -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
```
- docker run 固定语法
- -dit 交互方式 d:后台运行 i:交互模式运行 t: 容器启动后会进入其命令行 加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。 本语句后面需要加入命令行语句
- --name tracker 为创建的容器命名为tracker
- --network=host表示使用当前网络主机
- -v 目录映射 冒号左边是主机的目录 冒号右边是容器的目录
- delron/fastdfs 镜像名字
- tracker 程序的名字 可以让其启动
##### 3. 开启storage容器
> **3.开启storage容器**
>
> - TRACKER_SERVER=Tracker的ip地址:22122(Tracker的ip地址不要使用127.0.0.1)
> - 我们将 storage 运行目录映射到宿主机的 `/var/fdfs/storage`目录中。
```bash
$ sudo docker run -dti --name storage --network=host -e TRACKER_SERVER=192.168.103.158:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage
```
-e 额外设置的参数 TRACKER_SERVER=192.168.103.158:22122 : 告诉storage,tracker的ip和端口
- **注意:如果无法重启storage容器,可以删除/var/fdfs/storage/data目录下的fdfs_storaged.pid 文件,然后重新运行storage。**
##### 4.FastDFS客户端上传文件
###### 1.安装包
```bash
$ pip install fdfs_client-py-master.zip
$ pip install mutagen
$ pip isntall requests
```
以上三项都需要在虚拟环境中安装
第一项是本地文件
###### **2.准备FastDFS客户端扩展的配置文件**
- `meiduo_mall.utils.fastdfs.client.conf`
![1559237663674](assets/1559237663674.png)
连接实例
```python
# 1. 导入FastDFS客户端扩展
from fdfs_client.client import Fdfs_client
# 2. 创建FastDFS客户端实例 参数为配置文件
client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
# 3. 调用FastDFS客户端上传文件方法
ret = client.upload_by_filename('/Users/zhangjie/Desktop/kk.jpeg')
```
```python
ret = {
'Group name': 'group1',
'Remote file_id': 'group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg',
'Status': 'Upload successed.',
'Local file name': '/Users/zhangjie/Desktop/kk.jpeg',
'Uploaded size': '69.00KB',
'Storage IP': '192.168.103.158'
}
ret = {
'Group name': 'Storage组名',
'Remote file_id': '文件索引,可用于下载',
'Status': '文件上传结果反馈',
'Local file name': '上传文件全路径',
'Uploaded size': '文件大小',
'Storage IP': 'Storage地址'
}
```
###### 3. 浏览器下载并渲染图片
协议:
http
IP地址:本机ip
- Nginx服务器的IP地址。
- 因为 FastDFS 擅长存储静态文件,但是不擅长提供静态文件的下载服务,所以我们一般会将 Nginx 服务器绑定到 Storage ,提升下载性能。
端口:8888
- Nginx服务器的端口。
- 这个服务器是在镜像文件中自动安装的
路径:group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg
文件在Storage上的文件索引。
完整图片下载地址
http://192.168.103.158:8888/group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg |
|