前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >美多商城项目(五)

美多商城项目(五)

作者头像
小闫同学啊
发布2019-07-18 14:48:12
1.1K0
发布2019-07-18 14:48:12
举报
文章被收录于专栏:小闫笔记小闫笔记

正文共: 7875字 8图 预计阅读时间: 20分钟

每日分享

I would rather die of passion than of boredom.

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

小闫语录

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

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

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

美多商城项目(五)

1.typroa中画流程图

1.1横向流程图

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

代码示例

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

图表示例

1.2纵向流程图

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

代码示例

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

图表示例

2.数据缓存

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

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

代码语言:javascript
复制
GET /areas/:获取所有省级地区的信息

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

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

访问流程

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

2.2使用缓存

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

2.2.1安装
代码语言:javascript
复制
pip install drf-extensions
2.2.2使用方法
直接添加装饰器

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

代码语言:javascript
复制
class CityView(views.APIView):
    @cache_response()
    def get(self, request, *args, **kwargs):
        ...

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

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

代码语言:javascript
复制
@cache_response(timeout=60*60, cache='default')

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

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

代码语言:javascript
复制
# 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扩展类。

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

代码语言:javascript
复制
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中,且设置有效期,可以通过在配置文件中定义的方式来实现。

在配置文件中增加

代码语言:javascript
复制
# DRF扩展
REST_FRAMEWORK_EXTENSIONS = {
    # 缓存时间
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,
    # 缓存存储
    'DEFAULT_USE_CACHE': 'default',
}

3.用户地址

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

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

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

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

代码语言:javascript
复制
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模型类添加默认地址

代码语言:javascript
复制
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登录用户地址新增
代码语言:javascript
复制
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参数额外添加数据,如

代码语言:javascript
复制
serializer = AccountSerializer(account, context={'request': request})

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

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

c.调用ModelSerializer中create方法。

3.2.2获取登录用户地址数据
代码语言:javascript
复制
API: GET /addresses/
参数:
    通过请求头传递jwt token
响应:
    {
        "user_id":"用户id",
        "default_address_id":"用户默认地址id",
        "limit":"用户地址最大数量",
        "addresses":"用户地址"
    }

业务逻辑

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

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

3.2.3删除(逻辑删除)用户指定地址
代码语言:javascript
复制
API: DELETE /addresses/(?P<pk>\d+)/
参数:
    通过url地址传递地址的pk
    通过请求头传递jwt token
响应:
    状态码204

业务逻辑

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

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

3.返回应答。

3.2.4修改登录用户指定地址
代码语言:javascript
复制
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设置登录用户默认地址
代码语言:javascript
复制
API: PUT /addresses/(?P<pk>\d+)/status/
参数:
    通过url地址传递地址的pk
    通过请求头传递jwt token
响应:
    {
        "message":"OK"
    }

业务逻辑

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

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

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

3.2.6修改登录用户指定地址标题
代码语言:javascript
复制
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中有哪些镜像

代码语言:javascript
复制
docker image ls

拉取镜像到本地docker

代码语言:javascript
复制
docker image pull ...

删除docker镜像

代码语言:javascript
复制
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.地址管理-地址新增

代码语言:javascript
复制
self.get_serializer(...)

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

4.商品数据存储

商品存储数据表设计。

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

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

5.FDFS文件存储系统

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

传文件的内部过程

6.Docker

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

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

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • 美多商城项目(五)
    • 1.typroa中画流程图
      • 1.1横向流程图
      • 1.2纵向流程图
    • 2.数据缓存
      • 2.1网站性能优化-数据缓存
      • 2.2使用缓存
    • 3.用户地址
      • 3.1设置默认地址
      • 3.2地址管理
    • 4.商品部分
      • 4.1商品部分用户表设计
      • 4.2商品数据存储
      • 4.3FDFS文件存储系统
      • 4.4Docker
    • 总结回顾
      • 1.视图集对象action属性使用场景
      • 2.网站性能优化-数据缓存
      • 3.地址管理-地址新增
      • 4.商品数据存储
      • 5.FDFS文件存储系统
      • 6.Docker
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档