在线教育平台——购物车功能实现

本文最后更新于:2024年7月6日 早上

依赖软件:Django\redis

测试工具:postman

redis中购物车数据存储结构

  • redis最外层的key的实际意义是”luffy_shopping_car_userid_courseid”,也就是最后的两个数字分别代表的用户ID与需要加入购物车的课程ID
  • 每个单独的课程中,包含课程名称,课程图片,课程价格策略,当前选中策略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
redis: {
"luffy_shopping_car_1_1":
{
"title": "Linux基础",
"img": "2.png",
"policy": {
"2": {
"period": 60,
"period_display": "2个月",
"price": 1500
}
},
"default_policy": "2"
},
"luffy_shopping_car_1_3": {
...
}
}

实现思路

条件结构流程图

代码

在setting中设置redis配置:

1
2
3
4
5
6
7
8
9
10
11
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://yourip:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100},
"PASSWORD": "yourpassword",
}
}
}

路由设置urls.py:

1
url(r'^shopping_cart/$', shopping_cart.ShoppingCart.as_view()),

基于restframework的视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Author : Young
@Email : hyc554@outlook.com
@site : http://www.cnblogs.com/huang-yc/
@File : shopping_cart.py
@version : 1.0
@Time : 2018/11/4 20:51
Description about this file:

"""
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ViewSetMixin
from django_redis import get_redis_connection
from utils.response_dict import BaseResponse
from api.views.auth import YcAuth
from api import models
from utils.error import PricePolicyInvalid
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
import json


class ShoppingCart(APIView):
authentication_classes = [YcAuth]
conn = get_redis_connection('default')

def post(self, request, *args, **kwargs):
"""
向购物车中添加商品
:param request:
:param args:
:param kwargs:
:return:
"""
ret = BaseResponse()
try:
# 在这里获得用户的课程ID与价格策略ID
course_id = int(request.data.get('course_id'))
policy_id = int(request.data.get('policy_id'))

# 2. 获取专题课信息
course = models.Course.objects.get(id=course_id)

# 3.获取课程相关的所有价格策略
price_policy_list = course.price_policy.all()
price_policy_dict = {}
for item in price_policy_list:
price_policy_dict[item.id] = {
"period": item.valid_period,
"period_display": item.get_valid_period_display(),
"price": item.price
}
print(price_policy_dict)
if policy_id not in price_policy_dict:
raise PricePolicyInvalid('价格策略不合法')
# 5. 将购物信息添加到redis中
# self.conn
# car_key = "luffy_shopping_car_%s_%s"
car_key = settings.SHOPPING_CART_KEY % (request.auth.user_id, course_id,)
car_dict = {
'title': course.name,
'img': course.course_img,
'default_policy': policy_id,
'policy': json.dumps(price_policy_dict)
}
# conn = get_redis_connection("default")
self.conn.hmset(car_key, car_dict)
ret.data = '添加成功'


except PricePolicyInvalid as e:
ret.data = 2001
ret.error = e.msg
except ObjectDoesNotExist as e:
ret.data = 2002
ret.error = '课程不存在'


except Exception as e:
ret.code = 1001
ret.data = '获取购物车数据失败'
return Response(ret.dict)

def delete(self, request, *args, **kwargs):
ret = BaseResponse()
try:
course_id_list = request.data.get('courseids')
key_list = [settings.SHOPPING_CART_KEY % (request.auth.user_id, course_id,) for course_id in course_id_list]
self.conn.delete(*key_list)
except Exception as e:
ret.code = 1002
ret.error = "删除失败"

return Response(ret.dict)

def patch(self, request, *args, **kwargs):
ret = BaseResponse()
try:
course_id = int(request.data.get('course_id'))
policy_id = str(request.data.get('policy_id'))

key = settings.SHOPPING_CART_KEY % (request.auth.user_id, course_id)

if not self.conn.exists(key):
ret.code = 1002
ret.error = "购物车中不存在此课程"
return Response(ret.dict)
# 3. redis中获取所有的价格策略
# 请注意这里对redis里的数据进行读取的操作
policy_dict = json.loads(str(self.conn.hget(key, 'policy'), encoding='utf-8'))
if policy_id not in policy_dict:
ret.code = 1003
ret.error = "价格策略不合法"
return Response(ret.dict)

self.conn.hset(key, 'default_policy', policy_id)
ret.data = "修改成功"

except Exception as e:
ret.code = 2003
ret.error = '修改数据失败'

return Response(ret.dict)

def get(self, request, *args, **kwargs):
"""
查看购物车中所有的商品
:param request:
:param args:
:param kwargs:
:return:
"""
ret = BaseResponse()
try:
key_match = settings.SHOPPING_CART_KEY % (request.auth.user_id, "*")

course_list = []

for key in self.conn.scan_iter(key_match, count=10):
info = {
"title": self.conn.hget(key, 'title').decode('utf-8'),
"img": self.conn.hget(key, 'img').decode('utf-8'),
"policy": json.loads(self.conn.hget(key, 'policy').decode('utf-8')),
"default_policy": self.conn.hget(key, 'default_policy').decode('utf-8')
}
course_list.append(info)
ret.data = course_list
except Exception as e:
ret.code = 1002
ret.error = "获取失败"
return Response(ret.dict)


在线教育平台——购物车功能实现
https://yance.wiki/在线教育平台——购物车功能实现/
作者
Yance Huang
发布于
2019年5月5日
许可协议