美多商城项目(八)

阅读: 评论:0

美多商城项目(八)

美多商城项目(八)

正文共: 8098字 5图
预计阅读时间: 21分钟

项目仓库

.git

结合代码查看笔记,效果更佳。笔记只是记录重点或者难点。

每日分享

It is our attitude at the beginning of a difficult task which, more than anything else, will affect its successful outcome.

我们在开始做一件富有挑战性的任务时,对于成功的影响,没有什么比我们的态度更为关键的了。

小闫语录

在大一的时候,英语老师曾经送给我们一句话『Attitude is everything.』态度决定一切。其实一件事成功与否,在这份工作上是否有建树,从一开始就决定了,那便是我们对其的态度。客观的困难不足以阻挡前进的脚步,畏惧的态度才是失败的根本原因,其他的事情就算是直接原因,那也只是『压死骆驼身上的最后一根稻草』。有着必胜的决心,不畏难的坚定,端正的态度,前方路上的困难都将是小的磕磕绊绊,你的成功从开始的这一刻便已注定,加油!

美多商城项目(八)

1.项目每次启动前开启的任务

1.前端服务器live-server开启(在静态文件目录下执行)

live-server

2.开启celery任务(在celery_task上一级目录终端进行输入)

celery -A celery_task.main worker -l info

3.开启定时任务

# 添加定时任务到系统中
python manage.py crontab add
# 显示已经激活的定时任务
python manage.py crontab show
# 移除定时任务
python manage.py crontab remove

4.开启tracker服务器

docker container start tracker

5.开启storage服务器

docker container start storage

6.开启elasticsearch服务器

docker container start elasticsearch

7.进入redis查看

# 进入redis
redis-cli
# 选择数据库
select <数据库序号>

8.进入mysql数据库

mysql -h<主机地址> -P<端口号> -u<用户名> -p<密码>

2.购物车记录添加

API: POST /cart/
参数:通过请求头传递jwt token{"sku_id":"添加商品id","count":"数量","selected":"勾选状态", # 可以不传,默认是勾选状态}
响应:{"sku_id":"添加商品id","count":"数量","selected":"勾选状态"}

2.1业务逻辑

1.获取参数并进行校验(参数完整,sku_id商品是否存在,商品库存是否足够[可有可无,添加购物车可要可不要,下单时必须有])。

2.获取校验之后的数据。

3.获取user。

4.保存用户的购物车记录。

4.1如果用户已经登录,在redis中保存用户的购物车记录。

4.1.1获取redis链接。

hash:在redis hash中存储用户购物车添加的商品id和数量count。

如果购物车已经添加过该商品,数量需要进行累加,如果未添加,直接添加一个新元素。

hincrby

hincrby <key> <field> <increment>

给redis hash中指定field属性的值累加increment,如果field属性不存在,直接添加一个新的属性和值。

set: 在redis set中存储用户购物车勾选的商品id集合中的元素是唯一的

sadd

sadd <key> <member> ...

向redis set中添加元素,集合中元素是唯一的。

查看redis中是否存在。

# hash中查看所有的域field和他的值value
hgetall xxx
# set中获取key域集合的所有元素
smembers <key>

4.2如果用户未登录,在cookie中保存用户的购物车记录。

4.2.1获取原始cookie的购物车数据。

4.2.2解析cookie中购物车数据。

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

4.2.3如果购物车已经添加过该商品,数量需要进行累加。

通过看商品的id是不是在购物车数据字典中,可以得知是否添加过。

4.2.3如果购物车没有添加过该商品,直接添加一个新元素。

5.返回应答,购物车记录添加成功。

5.1设置cookie中购物车数据

cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()

如过出现认证未通过,可以重写父类APIView中的perform_authentication方法,直接pass跳过认证。我们在获取用户的时候使用request.user也会触发认证机制,我们可以手动对错误进行捕获而不让其报错停止。如果进行访问的时候没有传递jwt用户,是不会进行jwt验证的,会将其作为匿名用户处理。

3.购物车记录获取

API: GET /cart/
参数:通过请求头传递jwt token
响应:[{"id":"商品id","name":"商品名称","price":"商品价格","default_image_url":"默认图片","count":"数量","selected":"勾选状态"},...]

3.1业务逻辑

1.获取用户的购物车记录

1.1如果用户已登录,从redis中获取用户的购物车记录。

1.1.1获取redis链接

redis_conn = get_redis_connection('cart')

1.1.2从redis hash中获取用户购物车中添加的商品id和对应的数量count

hgetall

hgetall <key>

获取redis hash中所有的属性和值

1.1.3从redis set中获取用户购物车中勾选的商品id

smembers

smembers <key>

获取redis set中所有的元素

1.2如果用户未登录,从cookie中获取用户的购物车记录。

1.2.1获取cookie中购物车的数据。如果没有数据是None。

1.2.2解析cookie中购物车数据

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

2.根据用户购物车中商品id获取对应商品的数据。

2.1给sku对象增加属性count和selected,分别保存该商品在购物车中添加数据和勾选状态。

3.将购物车商品数据序列化并返回。

3.1添加购物车商品序列化器类。

3.2将数据序列化并返回。

4.购物车记录修改

API: PUT /cart/
参数:通过请求头传递jwt token{"sku_id":"商品id","count":"修改数量","selected":"修改勾选状态"}
响应:{"sku_id":"商品id","count":"修改数量","selected":"修改勾选状态"}

4.1业务逻辑

1.获取参数并进行校验(参数完整性,sku_id商品是否存在,商品的库存)。

1.1获取校验之后的数据。

1.2获取user。

调用request.user会触发DRF框架认证过程。

2.修改用户的购物车记录。

2.1如果用户已经登录,修改redis中对应的购物车记录。

2.1.1获取redis链接。

2.1.2修改redis hash中商品id对应数量count。

hset

hset <key> <field> <value>

将redis hash中指定的field属性值设置为value。

2.1.3修改redis set中勾选的商品id。

2.1.3.1勾选,那么添加新元素。

sadd

sadd <key> <member> ...

向redis set中添加元素,集合中元素是唯一的。

2.1.3.2取消勾选,将其移除。

srem移除

srem <key> <members> ...

从redis set中移除指定的元素,有则移除,无则忽略。

2.1如果用户没有登录,修改cookie中对应的购物车记录。

2.1.1获取cookie中的购物车数据。

2.1.2如果购物车没有数据。

2.1.3如果购物车中有数据,解析cookie中的购物车数据。

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

如果获取的字典为空,表示购物车无数据。

2.1.4修改购物车数据。

3.返回应答,购物车记录修改成功。

3.1设置cookie中购物车数据。

cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()

3.2返回应答,购物车记录修改成功。


总结

1.购物车记录增加

hincrby sadd

2.购物车记录获取

hgetall smembers

3.购物车记录修改

hset sadd srem

对于上面的三个接口,都需要考虑用户是登录还是未登录。

让视图跳过DRF框架认证过程。


5.购物车记录删除

API: DELETE /cart/
参数:通过请求头传递jwt token{"sku_id":"商品id"}
响应:{"sku_id":"商品id"}

5.1业务逻辑

1.获取商品skuid并进行校验(skuid必传,sku_id对应商品是否存在)。

1.1获取校验之后的数据。

1.2获取用户,防止触发DRF框架的认证机制,对错误进行捕获。

2.删除用户的购物车记录。

2.1如果用户已登录,删除redis中对应的购物车记录。

2.1.1获取redis链接

2.1.2从redis hash中删除对应商品的id和数量count

hdel

hdel <key> <field> ...

删除redis hash中指定的field属性和值。

2.1.3从redis set中删除对应商品的id

srem移除

srem <key> <members> ...

从redis set中移除指定的元素,有则移除,无则忽略。

2.2如果用户未登录,删除cookie中对应的购物车记录。

2.2.1获取cookie中的购物车记录。

2.2.2如果无数据,直接返回204;如果有数据需要解析cookie中购物车数据。

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

2.2.3删除对应的购物车记录。

2.2.4重新设置cookie购物车数据。

cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()

3.返回应答,购物车记录删除成功。

6.全选和取消全选

API: PUT /cart/selection/
参数:通过请求头传递jwt token{"selected": "勾选状态", # True:全选, False:取消全选 }
响应:{"message": "OK"}

6.1业务逻辑

1.获取参数selected并进行校验(selected必传)。

1.1获取校验之后的selected。

1.2获取用户。

2.设置用户购物车记录勾选状态。

2.1如果用户已登录,设置redis中用户购物车记录勾选状态。

2.1.1获取redis链接。

2.1.2从redis hash中获取用户购物车中所有商品的id。

2.1.3全选:将用户购物车所有商品的id添加到redis set中。

2.1.4全不选:将用户购物车所有商品的id从redis set中移除。

2.2如果用户未登录,设置cookie中用户购物车记录勾选状态。

2.2.1获取cookie的购物车记录。

2.2.2解析cookie中的购物车数据

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

2.2.3设置cookie购物车记录勾选状态。

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

3.1设置cookie中的购物车数据

cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()

7.购物车记录合并

7.1需求

用户登录时,将cookie中的购物车数据合并到登录用户redis购物车记录中。

7.2实现

只需将购物车记录合并封装成函数,然后在登录过程进行调用。

登录过程调用合并购物车函数

1.普通账户密码登录。

2.QQ登录。

7.2.1购物车记录合并方案
# 假如id为2的用户登录之前
# cookie中的购物车记录如下
{11:{'count': 1,'selected': False},15: {'count': 2,'selected': True}
}
cart_dict = {11: 1,15: 2
}
cart_selected_add = [15]
cart_selecte_remove = [11]
# redis中的购物车记录如下
cart_2: {'11': '2','16': '3','9': '1'
}
cart_selected_2:('11', '9')

如果id为2的用户进行了登录,需要将cookie中的购物车数据合并到用户redis购物车记录中,如何进行合并?

答:当进行购物车记录合并时,如果cookie中的购物车数据和redis中的购物车数据发生了冲突,直接以cookie中的购物车数据为准,用cookie中的购物车数据去覆盖redis中对应的数据。如果没有冲突,都进行保留。

cart_2: {'11': '1','15': '2','16': '3','9': '1'
}
cart_selected_2('15','9')

11的数据因为发生了冲突,覆盖后,取消了勾选。

7.2.2举例

假如id为2的用户登录之前,cookie中的购物车记录如下:

{1: {'count': 3,'selected': False},3: {'count': 2,'selected': True},5: {'count': 2,'selected': True}
}

redis中的购物车记录如下:

cart_2: {'1': '2','5': '1','7': '3'
}
cart_selected_2: ('1', '7')

合并之后的数据如下:

cart_2: {'1': '3','3': '2','5': '2','7': '3'
}
cart_selected_2: ('3', '5', '7')

7.3封装合并购物车记录函数

7.3.1目的

将cookie中的购物车记录合并到登录用户的redis记录中。

7.3.2业务逻辑

1.获取cookie中购物车记录。

2.如果cookie购物车中无数据,就不需要合并了。

3.如果cookie购物车中有数据,需要解析cookie中的购物车数据。

cart_dict = pickle.loads(base64.b64decode(cookie_cart))

4.如果解析出来的字典为空,表明cookie购物车中无数据,也不需要合并。

5.将cookie中购物车记录合并到登录用户的redis记录中

6.组织一个字典,存储cookie购物车记录中添加的商品id和对应数量count。此字典中的数据在进行购物车记录合并时需要设置到redis hash中。

7.组织一个列表,存储cookie购物车记录中被勾选的商品的id。此列表中的商品的id在进行购物车记录合并时,需要添加到redis set中。

8.组织一个列表,存储cookie购物车记录中未被勾选商品的id。此列表中商品id在进行购物车记录合并时需要从redis set中移除。

9.遍历解析之后的字典,将勾选与未勾选的数据分别加入对应的列表中。

10.合并:将组织的字典中key和value作为属性和值设置到redis对应的hash元素中。

11.将需要添加到redis的列表中商品id添加到redis对应的set元素中。

12.将需要从redis中移除的列表中商品的id从redis对应的set元素中移除。

13.删除cookie中购物车数据。

response.delete_cookie('cart')

hmset

hmset <key> <field> <value> [<field> <value>....]

同时将多个field属性和值设置到哈希表key中。此命令会覆盖以存在的属性。

7.4修改登录视图

rest_framework_jwt提供的obtain_jwt_token视图,
实际从rest_framework_jwt.views.ObtainJSONWebToken类视图而来,
我们可以重写此类视图里的post方法来添加合并逻辑。
登录视图
from rest_framework_jwt.views import ObtainJSONWebToken
class UserAuthorizeView(ObtainJSONWebToken):"""用户认证"""def post(self, request, *args, **kwargs):# 调用父类的方法,获取drf jwt扩展默认的认证用户处理结果response = super().post(request, *args, **kwargs)# 仿照drf jwt扩展对于用户登录的认证方式,判断用户是否认证登录成功# 如果用户登录认证成功,则合并购物车serializer = _serializer(data=request.data)if serializer.is_valid():user = serializer.('user')response = merge_cart_cookie_to_redis(request, user, response)return response

修改路径users/urls.py

urlpatterns = [...# url(r'^authorizations/$', obtain_jwt_token),url(r'^authorizations/$', views.UserAuthorizeView.as_view()),...
]
QQ登录

修改oauth/serializers.py中的序列化器

class OAuthQQUserSerializer(serializers.ModelSerializer):...def create(self, validated_data):...# 向视图对象中补充user对象属性,以便在视图中使用t['view'].user = userreturn user

修改oauth/views.py中的视图

class OAuthQQUserView(CreateAPIView):"""获取QQ用户对应的美多商城用户"""serializer_class = OAuthQQUserSerializerdef get(self, request):...else:reponse = Response({'token': token,'username': user.username,'user_id': user.id})# 合并购物车response = merge_cart_cookie_to_redis(request, user, response)return responsedef post(self, request, *args, **kwargs):response = super().post(request, *args, **kwargs)# 合并购物车response = merge_cart_cookie_to_redis(request, self.user, response)return response

优质文章推荐:

公众号使用指南

redis操作命令总结

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

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

Django相关知识点回顾

本文发布于:2024-02-02 02:10:56,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170681434340722.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:商城   项目
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23