美多商城项目(五)

简介: 美多商城项目(五)

每日分享

I would rather die of passion than of boredom.

我宁愿死于激情而不是无聊。

小闫语录

赵鑫珊在《哲学与当代世界》中曾说过这样一句话『自古至今,人类最伟大的精神产品(科学的,艺术的和哲学的),无一不是出自一腔激情』。激情是一种积极的态度,它会激发我们的潜能;激情是一种神奇的药剂,它会使我们周围的人被感染;激情是成功的必备因素,它会使我们把事情做至极致。有人充满激情奋斗终身,也有人自甘平凡,碌碌无为,得过且过。人生需要激情,年轻人更需要激情,否则在社会进步的浪潮里终有一天会被淘汰。

不要戴着『佛系』的帽子,终其一生。你要承认自己的怯懦,承认自己的逃避,不要为自己找任何托词,你只是在掩耳盗铃罢了。你敢说你不羡慕那些物质优渥的人吗?你敢说你不想超越身边的某个人吗?你只是怕努力之后没有得到想要的,你只是怕最后的结果是你比不过某个人。然后就谎称你不想、谎称不屑于去做,自居清高,实则是懦弱,逃避。充满激情,认真做好每一件事,重要的不是结果,而是过程。不要攀比,不要嘲笑某人,因为每个人都有其他人无法比的一些闪光点。

无聊的一生平平淡淡,难道你到了这个世上只是为了呼吸一下空气,看看其他人的辉煌美好吗?充满激情的度过每一天,有可能是大起大落,有可能是一路惊喜不断,但是为了想要的生活不断的努力,活成别人羡慕的模样不好吗?



美多商城项目(五)

1.typroa中画流程图

1.1横向流程图

注意:横向的流程图,代码块中首行标明graph LR,代码块标明语言是mermaid

代码示例

```mermaid
graph LR
A[方形]-->B(圆角)
    B-->C{条件a}
    C-->|a=1|D[结果1]
    C-->|a=2|E[结果2]
    F[横向流程图]
```

图表示例

1.2纵向流程图

注意:纵向的流程图,代码块中首行标明graph TD,代码块标明语言是mermaid

代码示例

```mermaid
graph TD
A[方形]-->B(圆角)
    B-->C{条件a}
    C-->|a=1|D[结果1]
    C-->|a=2|E[结果2]
    F[纵向流程图]
```

图表示例

2.数据缓存

2.1网站性能优化-数据缓存

前面的文章中我们写过这样一个接口:

  1. GET /areas/:获取所有省级地区的信息

假如1分钟之内有500个用户访问了GET /areas/,服务器就需要查询500次数据库,但是最终每个用户获取到的结果是一样的。为了减少数据库的查询次数,提高效率,让用户体验度上升,我们可以使用数据缓存

数据缓存:把经常被用户访问的数据放到缓存(redis)中,当用户来访问时,直接从缓存中获取数据进行返回,只有缓存中不存在时才查询数据库。

访问流程

客户端向服务器访问数据的时候,服务器先到redis缓存中获取对应的数据,如果获取到数据,直接进行返回;如果获取不到数据,再去查询数据库。并且在查询出数据,返回结果之前,先将查询的结果存到缓存中,便于下次使用。

2.2使用缓存

在Django REST framework中使用缓存,可以通过 drf-extensions扩展来实现。

2.2.1安装

  1. pip install drf-extensions

2.2.2使用方法

直接添加装饰器

可以在使用restframeworkextensions.cache.decorators中的cache_response装饰器来装饰返回数据的类视图的对象方法,如

class CityView(views.APIView):
    @cache_response()
    def get(self, request, *args, **kwargs):
        ...

装饰器的作用:访问接口的时候,会先到缓存中进行获取,没有的话才会执行接口函数。

cache_response装饰器可以接收两个参数

@cache_response(timeout=60*60, cache='default')

timeout 缓存时间

cache 缓存使用的Django缓存后端(即CACHES配置中的键名称)

如果在使用cache_response装饰器时未指明timeout或者cache参数,则会使用配置文件中的默认配置,可以通过如下方法指明:

# DRF扩展
REST_FRAMEWORK_EXTENSIONS = {
    # 缓存时间
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,
    # 缓存存储
    'DEFAULT_USE_CACHE': 'default',
}

DEFAULTCACHERESPONSE_TIMEOUT 缓存有效期,单位秒

DEFAULTUSECACHE 缓存的存储方式,与配置文件中的 CACHES的键对应。

注意,cache_response装饰器既可以装饰在类视图中的get方法上,也可以装饰在REST framework扩展类提供的list或retrieve方法上。使用cacheresponse装饰器无需使用method_decorator进行转换。

使用drf-extensions提供的扩展类

drf-extensions扩展对于缓存提供了三个扩展类:

ListCacheResponseMixin

用于缓存返回列表数据的视图,与ListModelMixin扩展类配合使用,实际是为list方法添加了cache_response装饰器

RetrieveCacheResponseMixin

用于缓存返回单一数据的视图,与RetrieveModelMixin扩展类配合使用,实际是为retrieve方法添加了cache_response装饰器

CacheResponseMixin

为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。

三个扩展类都是在 rest_framework_extensions.cache.mixins中。

2.2.3为省市区视图添加缓存

因为省市区视图使用了视图集,并且视图集中有提供ListModelMixin和RetrieveModelMixin的扩展(由ReadOnlyModelViewSet提供),所以可以直接添加CacheResponseMixin扩展类。

修改返回省市区信息的视图

from rest_framework_extensions.cache.mixins import CacheResponseMixin
class AreasViewSet(CacheResponseMixin,ReadOnlyModelViewSet):
    """
    行政区划信息
    """
    pagination_class = None  # 区划信息不分页
    def get_queryset(self):
        """
        提供数据集
        """
        if self.action == 'list':
            return Area.objects.filter(parent=None)
        else:
            return Area.objects.all()
    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action == 'list':
            return AreaSerializer
        else:
            return SubAreaSerializer

2.2.4缓存数据保存位置与有效期设置

我们想把缓存数据保存在redis中,且设置有效期,可以通过在配置文件中定义的方式来实现。

在配置文件中增加

# DRF扩展
REST_FRAMEWORK_EXTENSIONS = {
    # 缓存时间
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,
    # 缓存存储
    'DEFAULT_USE_CACHE': 'default',
}

3.用户地址

用户在添加收货地址的时候,我们需要将用户的地址进行保存,因此需要先创建一个模型类,然后迁移生成表。数据库有用户地址表后,我们就可以将用户地址保存到数据库了。

数据库的表格一般都是DBA进行设计的,我们不需要深入了解,所以此处不做过多的阐述。

在用户模型类中有一个小点回顾一下:

ordering 表示的是表名在进行Address查询时,默认使用的排序方式。默认是升序,如果想改为降序,只需要在前面添加一个减号 -

ordering = ['-update_time']

其中updatetime代表的是按照updatetime进行排序。

3.1设置默认地址

可以在用户地址模型类中添加一个标记 is_default,如果是默认地址,将标记改为True。但是这种方法比较麻烦,修改需要两步,先将原来的默认地址标记改为False,再将要设置默认地址的标记改为True。我们可以换一种方法:在用户表中添加一个字段。

用户表

ID(用户ID) ... DEFAULT_ADDRESS_ID(默认地址ID)
1 ... 2

在用户表中,我们只需要修改默认地址id。例如我想更改用户A的默认地址为B,直接将默认地址id更改B的id就可以了,只需一步,比上一种方法要好的多。

设置步骤

为User模型类添加默认地址

class User(AbstractUser):
    ...
    default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True, on_delete=models.SET_NULL, verbose_name='默认地址')
    ...

3.2地址管理

3.2.1登录用户地址新增

API: POST /addresses/
参数:
    通过请求头传递jwt token
    {
        "title":"地址标题",
        "receiver":"收货人",
        "province_id":"省id",
        "city_id":"市id",
        "district_id":"区id",
        "place":"详细地址",
        "mobile":"手机号",
        "tel":"电话", # 可以不传递
        "email":"邮箱" # 可以不传递
    }
响应:
    {
        "id":"地址id",
        "title":"地址标题",
        "receiver":"收货人",
        "province":"省名称",
        "city":"市名称",
        "district":"区县名称",
        "province_id":"省id",
        "city_id":"市id",
        "district_id":"区id",
        "place":"详细地址",
        "mobile":"手机号",
        "tel":"电话", # 可以不传递
        "email":"邮箱" # 可以不传递
    }

因为用户界面显示的是省市县的名称,所以我们响应数据不能传递id,因此需要添加三个数据,将名称返回。

业务逻辑

1.先设置用户权限,只有认证用户才可以对此接口进行访问。

2.判断用户的地址数量是否超过上限。

3.获取参数并进行校验(参数完整性,手机号格式,邮箱格式)。

4.创建并保存新增地址数据。

5.将新增地址数据序列化并返回。

写代码之前,先定义地址的序列化器类。

因为我们需要的字段有点多,我们可以不用field指定字段,而是使用exclude排除我们不需要的几个字段即可。

对于没有的字段provinceid、cityid和district_id,我们需要自己定义。

有些字段是序列化时使用,有些字段是反序列化时使用,因此我们需要对这些字段通过参数进行设置。

因为我们序列化时需要的是省市县的名称,所以我们在嵌套序列化的时候使用StringRelatedField方法。系统自动生成的时候,默认是序列化为主键,我们需要对其进行更改。

我们可以在序列化器类中定义validate_mobile方法来校验手机号。

ModelSerializer中的create不适用,因为我们新增的数据中没有user,但是用户表中是有这个字段的,而且是必填项,所以我们需要重写create方法,将user添加进去再调用系统的create方法将数据保存。

a.创建并保存新增地址数据。

b.获取登录用户对象。

除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如

  1. serializer =AccountSerializer(account, context={'request': request})

通过context参数附加的数据,可以通过Serializer对象的context属性获取。

self.get_serializer(...)创建序列化器对象时,会向序列化器对象的context属性中补充request参数,可以通过 序列化器对象.context['request']来获取request对象。

c.调用ModelSerializer中create方法。

3.2.2获取登录用户地址数据

API: GET /addresses/
参数:
    通过请求头传递jwt token
响应:
    {
        "user_id":"用户id",
        "default_address_id":"用户默认地址id",
        "limit":"用户地址最大数量",
        "addresses":"用户地址"
    }

业务逻辑

1.获取登录用户所有地址数据。

2.将地址数据序列化并返回。

3.2.3删除(逻辑删除)用户指定地址

API: DELETE /addresses/(?P<pk>\d+)/
参数:
    通过url地址传递地址的pk
    通过请求头传递jwt token
响应:
    状态码204

业务逻辑

1.根据pk获取指定的地址数据。

2.将地址的is_deleted设置为True。

3.返回应答。

3.2.4修改登录用户指定地址

API: PUT /addresses/(?P<pk>\d+)/
参数:
    通过url地址传递地址的pk
    通过请求头传递jwt token
    {
        "title":"地址标题",
        "receiver":"收货人",
        "province_id":"省id",
        "city_id":"市id",
        "district_id":"区id",
        "place":"详细地址",
        "mobile":"手机号",
    }
响应:
    {
        "id":"地址id",
        "title":"地址标题",
        "receiver":"收货人",
        "province":"省名称",
        "city":"市名称",
        "district":"区县名称",
        "province_id":"省id",
        "city_id":"市id",
        "district_id":"区id",
        "place":"详细地址",
        "mobile":"手机号",
        "tel":"电话", # 可以不传递
        "email":"邮箱" # 可以不传递
    }

业务逻辑

1.根据pk获取指定的地址数据。

2.获取参数并进行校验。

3.修改指定地址的数据。

4.返回修改地址序列化数据。

UpdateModelMixin中已经实现了update方法,而且满足我们的需求,所以我们可以不写这个方法。

3.2.5设置登录用户默认地址

API: PUT /addresses/(?P<pk>\d+)/status/
参数:
    通过url地址传递地址的pk
    通过请求头传递jwt token
响应:
    {
        "message":"OK"
    }

业务逻辑

1.根据pk查询指定的地址。

2.设置登录用户的默认地址。

3.返回应答,设置成功。

3.2.6修改登录用户指定地址标题

API: PUT /addresses/(?P<pk>\d+)/title/
参数:
    通过url传递地址的pk
    通过请求头传递jwt token
    通过请求体参数title
响应:
    {
        "id":"地址id",
        "title":"地址标题"
    }

业务逻辑

1.根据pk查询指定的地址。

2.获取title参数并校验(title必传)。

3.修改指定地址的标题并更新数据库。

4.返回应答,设置标题成功。

4.商品部分

4.1商品部分用户表设计

使用工具『StarUML』

首页广告数据表结构:

商品数据表结构:

4.2商品数据存储

SPU:属性值,特性相同的商品统称。例如:iPhoneX

SKU:涉及到某个具体规格的产品。例如:iPhoneX 红色 256G 全网通

MacBook Pro --->SPU

MacBook Pro 银色 512G 15.4寸---->SKU

4.3FDFS文件存储系统

淘宝架构师:余庆

七牛云:文件存储系统,花钱就能用,不需要自己进行维护。(小型公司使用居多)

FDFS:文件存储系统,自己搭建,自己进行维护。(大型公司一般自己搭建维护)

4.3.1概念

FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制, 充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

冗余处理:不同的人保存的相同的内容,可以只保存一份,节省空间。

备份:防止数据丢失。

负载均衡:多个服务器共同处理,提高效率。

线性扩容:方便后期扩容。

4.3.2架构

Tracker server:调度服务器,负责负载均衡和调度。

Storage server:存储服务器,负责进行文件的存储。不止一个。

4.3.3详细介绍

详细介绍请查看『我是个链接』一文。

4.4Docker

Docker 可以让开发者打包他们的应用以及依赖环境,将打包好的文件上传到其他Linux电脑上,使用docker加载之后可以直接进行使用。

4.4.1镜像(image)

打包的应用以及依赖包构成了一个docker镜像

镜像操作命令:

查看本地docker中有哪些镜像

  1. docker image ls

拉取镜像到本地docker

  1. docker image pull ...

删除docker镜像

  1. docker image rm 镜像名/镜像ID  

4.4.2容器(container)

把镜像运行起来之后变成了一个容器。

4.4.3C/S模型

Docker客户端只需向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并且返回结果。

4.4.4Registry(注册中心)

Docker 用 Registry 来保存用户构建的镜像。Registry 分为公共和私有两种。

4.4.5使用

详细安装使用步骤请查看『我是个链接』一文。

总结回顾

1.视图集对象action属性使用场景

重写getserializerclass和get_queryset,根据不同的action操作,返回不同的序列化器和不同的查询集。

2.网站性能优化-数据缓存

扩展:drf-extensions

cache_response装饰器:进行数据缓存设置和获取。

3.地址管理-地址新增

  1. self.get_serializer(...)

上面的代码在创建序列化器对象的时候,会向序列化器对象的context属性中补充request参数。

4.商品数据存储

商品存储数据表设计。

SPU:属性值,特性相同的商品统称。例如iPhoneX

SKU:涉及到某个具体规格的产品。例如:iPhoneX 红色 256G 全网通

5.FDFS文件存储系统

概念和架构看一下,做一个了解。

传文件的内部过程

6.Docker

将应用的依赖环境进行打包,将打包好的文件上传到其他Linux电脑上,使用docker加载之后可以直接进行使用。

镜像的操作命令再看一下。

相关文章
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的“我爱我家”地方特色农产品商城的详细设计和实现
基于SpringBoot+Vue的“我爱我家”地方特色农产品商城的详细设计和实现
39 2
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的城投公司企业人事管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的城投公司企业人事管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的大学生二手电子产品交易平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的大学生二手电子产品交易平台的详细设计和实现(源码+lw+部署文档+讲解等)
79 0
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的桂林旅游景点导游平台附带文章和源代码
基于SpringBoot+Vue的桂林旅游景点导游平台附带文章和源代码
51 1
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的南宁周边乡村游微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的南宁周边乡村游微信小程序的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的桂林旅游景点导游平台的设计与实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的桂林旅游景点导游平台的设计与实现(源码+lw+部署文档+讲解等)
|
6月前
|
开发框架 小程序 Java
免费开题报告|基于SpringBoot+Vue的校内跑腿平台
免费开题报告|基于SpringBoot+Vue的校内跑腿平台
免费开题报告|基于SpringBoot+Vue的校内跑腿平台
|
Linux 数据库 文件存储
美多商城项目(六)
美多商城项目(六)
|
存储 安全 数据安全/隐私保护
美多商城项目(二)
美多商城项目(二)
|
SQL JavaScript 前端开发
GitHub标星11.9k兼职项目!基于SpringBoot + VUE电商-分销商城系统
商城系统支持商家入驻,后端基于SpringBoot 研发,前端使用 Vue、uniapp开发, 系统全端全部代码开源 前后端分离,支持分布式部署,支持Docker,各个API独立,并且有独立的消费者。
下一篇
无影云桌面