您的当前位置:首页正文

购物车设计思路

2020-05-13 来源:小奈知识网
购物车设计思路

0.先在redis测试

# Author:Jesi

# Time : 2018/10/25 18:36import redisimport json

conn=redis.Redis(host=\"47.99.191.149\",port=6379,password='cyy520')# conn.flushall()# #购买的第⼀商品# data_dict={# 11:{

# 'title':'21天从⼊门到放弃',# 'src':'xxx.png'# }# }

# conn.hset('luffy_shopping_car','11',json.dumps(data_dict))# car = conn.hget('luffy_shopping_car','11')# car_str=str(car,encoding='utf-8')# car_dict=json.loads(car_str)# print(car_dict)

# car_dict[\"12\"]={

# 'title':'luffy_shopping_car',# 'src':'xxx2.png'# }

# print(car_dict)# print(conn.keys())# conn.flushall()

#添加课程

# redis_key=\"luffy_shopping_car_%s_%s\"%(6,12)

# conn.hmset(redis_key,{'title':'21天从⼊门到放弃','src':'xxx.png'})

#删除课程

# conn.delete('luffy_shopping_car_6_12')

#修改课程

# conn.hset('luffy_shopping_car_6_11','src','x1.png')

#查看所有课程

# print(conn.keys('luffy_shopping_car_6_*'))

# for item in conn.scan_iter('luffy_shopping_car_6_*',count=10):# course=conn.hgetall(item)# # print(course)

# for k,v in course.items():

# print(str(k,encoding='utf-8'),str(v,encoding='utf-8'))

正式开发购物车的接⼝:

因为购物车这种的有可能经常删除,修改等等,我们可以将这个东西放到redis中,速度更快,redis设置过期时间,如果长时间没有结算,那么应该把这个购物车清空。

添加URL

url(r'shoppingcar/$',shoppingcar.ShoppingCarViewSet.as_view({'post':'create'}))

在redis配置上django的redis

#redis配置CACHES = { \"default\": {

\"BACKEND\": \"django_redis.cache.RedisCache\",

\"LOCATION\": \"redis://47.99.191.149:6379\", #redis服务器地址 \"OPTIONS\": {

\"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",

\"CONNECTION_POOL_KWARGS\": {\"max_connections\": 100}, #最⼤连接池100 \"PASSWORD\": \"xxxx\", } }}

1.添加购物车接⼝

# Author:Jesi

# Time : 2018/10/26 9:18import jsonimport redis

from rest_framework.views import APIView

from rest_framework.viewsets import GenericViewSet,ViewSetMixinfrom rest_framework.response import Response

from django_redis import get_redis_connection #导⼊django_redisfrom utils.response import BaseResponse #导⼊状态信息基类from api.views.auth.auth import LuffyAuth #导⼊认证组件from api import models

from django.core.exceptions import ObjectDoesNotExist

from utils.exception import PricePolicyInvalid #⾃定制的价格策略⾮法异常from django.conf import settings

class ShoppingCarViewSet(ViewSetMixin,APIView): authentication_classes = [LuffyAuth,]

conn = get_redis_connection('default') # 拿到defalut这个redis连接池 def create(self,request,*args,**kwargs): '''

将课程添加到购物车 :param args:

:param kwargs: :return: '''

ret = BaseResponse()

self.conn.set(\"name\", \"egon\") try:

#1.获取⽤户提交的课程ID和价格策略ID[这⾥注意int⼀下] course_id=int(request.data.get(\"courseid\")) policy_id=int(request.data.get(\"policyid\"))

#2.获取专题课信息

course=models.Course.objects.filter(id=course_id).first()

#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)

       #{1: {'period': 3, 'period_display': '3天', 'price': 111.0}, 4: {'period': 30, 'period_display': '1个⽉', 'price': 399.0}} #4.判断⽤户提交的价格策略是否合法 if policy_id not in price_policy_dict: #价格策略不合法

raise PricePolicyInvalid(\"价格策略不合法\")

#5.将购物信息添加到redis中

car_key=settings.SHOPPING_CAR_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) #这⾥注意redis中需要将这⾥dumps⼀下才可以存⼊。 }

conn=get_redis_connection(\"default\") conn.hmset(car_key,car_dict) ret.data=\"添加成功!\"

except PricePolicyInvalid as e: #价格策略⾮法异常 ret.code=2001 ret.error=e.msg

except ObjectDoesNotExist as e: #捕捉课程不存在的异常 ret.code = 2001

ret.error = \"课程不存在\" except Exception as e: ret.code=1001

ret.error=\"添加失败\" return Response(ret.dict)

上⾯⽤到了⼀个认证的组件:

1.独⽴的认证组件,导⼊即可

LuffyAuth.py

from rest_framework.authentication import BaseAuthenticationfrom api import models

from rest_framework.exceptions import AuthenticationFailedclass LuffyAuth(BaseAuthentication):

def authenticate(self, request): \"\"\"

⽤户请求进⾏认证 :param request: :return: \"\"\"

# http://wwwww...c0ovmadfasd/?token=adfasdfasdf token = request.query_params.get('token')

obj = models.UserAuthToken.objects.filter(token=token).first() if not obj:

raise AuthenticationFailed({'code':1001,'error':'认证失败'}) return (obj.user.username,obj)

2.上⼀个⽤的封装好的返回信息的基类,导⼊通⽤。

response.py

class BaseResponse(object): '''

封装⼀个基础的字典 '''

def __init__(self): self.code = 1000 self.data = None self.error = None @property def dict(self):

return self.__dict__

3.exception.py

class PricePolicyInvalid(Exception): def __init__(self,msg): self.msg=msg

4.因为常⽤到这个redis的key,我们放到配置⽂件,业务中通过settings拿到直接⽤即可,不⽤⼀直写了。

settings.py

SHOPPING_CAR_KEY = \"luffy_shopping_car_%s_%s\"

最后在PY⽂件中测试⼀下,看⼀下redis到底存⼊了数据没有。

通过循环,拿到了购物车的数据,表⽰添加的接⼝开发完毕!

2.删除购物车

#删

def delete(self,request,*args,**kwargs): '''

购物车中删除课程 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse() try:

course_id_list=request.data.get(\"courseids\") #获取到要删除的课程ID,是⼀个列表,可以删除多个课程

key_list=[settings.SHOPPING_CAR_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)

3.修改购物车

#改

def patch(self,request,*args,**kwargs): '''

修改课程的价格策略 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse()

try:

#1.获取价格策略ID和课程ID

course_id=int(request.data.get(\"courseid\")) policy_id=int(request.data.get(\"policyid\"))

#2.拼接课程的key

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

print(key)

if not self.conn.exists(key): ret.code= 1002

ret.error=\"购物车不存在此课程\" return Response(ret.dict)

#3.在redis中获取所有价格策略:

policy_dict=json.loads(str(self.conn.hget(key,'policy'),encoding='utf-8')) #这⾥需要loads回来并且做⼀个utf-8的转换 print(policy_dict)

if str(policy_id) not in policy_dict: #可能出现⽤户私⾃修改价格策略,需要做⼀个判定 ret.code=1003

ret.error=\"价格策略不合法\" return Response(ret.dict)

#4.在购物车中修改该课程的默认价格策略

self.conn.hset(key,'default_policy',policy_id) #课程和价格策略全部合法后,进⾏⼀个修改。 ret.data=\"修改成功\" except Exception as e: ret.code=1001

ret.error=\"课程修改失败\" return Response(ret.dict)

4.查看购物车

#查

def get(self,request,*args,**kwargs): '''

查看购物车中所有的商品 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse() try:

current_user_id=request.auth.user_id

key_match=settings.SHOPPING_CAR_KEY%(current_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=\"1001\" ret.error=\"获取失败\" return Response(ret.dict)

获取到的结果显⽰如下:

{

\"code\": 1000, \"data\": [ {

\"title\": \"数学算数\", \"img\": \"451646\", \"policy\": { \"2\": {

\"period\": 3,

\"period_display\": \"3天\", \"price\": 222 } },

\"default_policy\": \"2\" }, {

\"title\": \"语⽂阅读\", \"img\": \"25852585.jpg\", \"policy\": { \"1\": {

\"period\": 3,

\"period_display\": \"3天\", \"price\": 111 }, \"4\": {

\"period\": 30,

\"period_display\": \"1个⽉\", \"price\": 399 } },

\"default_policy\": \"4\" } ],

\"error\": null}

View Code

完整源码:urls.py

from django.conf.urls import url

from api.views.course import coursehostfrom api.views.user import account

from api.views.course import newspapersfrom api.views.shopping import shoppingcar

urlpatterns = [

url(r'^login/$', account.loginView.as_view()),

url(r'^course/$', coursehost.CourseViewSet.as_view({\"get\": \"list\"})),

url(r'^course/(?P\\d+)/$', coursehost.CourseViewSet.as_view({\"get\": \"retrieve\"})),

url(r'^newspapers/', newspapers.NewsPapers.as_view({\"get\": \"list\"})),

url(r'^newspapers/(?P\\d+)/$', newspapers.NewsPapers.as_view({\"get\": \"retrieve\"})),

url(r'^newspapers/(?P\\d+)/agree/$', newspapers.AgreeView.as_view({'post': 'post'})),

url(r'shoppingcar/$',shoppingcar.ShoppingCarViewSet.as_view())

View Code

shoppingcar.py

# Author:Jesi

# Time : 2018/10/26 9:18import jsonimport redis

from rest_framework.views import APIView

from rest_framework.viewsets import GenericViewSet,ViewSetMixinfrom rest_framework.response import Responsefrom django_redis import get_redis_connectionfrom utils.response import BaseResponsefrom api.views.auth.auth import LuffyAuthfrom api import models

from django.core.exceptions import ObjectDoesNotExistfrom utils.exception import PricePolicyInvalidfrom django.conf import settings

class ShoppingCarViewSet(APIView): authentication_classes = [LuffyAuth,]

conn = get_redis_connection('default') # 拿到defalut这个redis连接池 #增

def post(self,request,*args,**kwargs): '''

将课程添加到购物车 :param args: :param kwargs: :return: '''

ret = BaseResponse()

self.conn.set(\"name\", \"egon\") try:

#1.获取⽤户提交的课程ID和价格策略ID[这⾥注意int⼀下] course_id=int(request.data.get(\"courseid\")) policy_id=int(request.data.get(\"policyid\"))

#2.获取专题课信息

course=models.Course.objects.filter(id=course_id).first() #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)

#4.判断⽤户提交的价格策略是否合法 if policy_id not in price_policy_dict: #价格策略不合法

raise PricePolicyInvalid(\"价格策略不合法\")

#5.将购物信息添加到redis中

car_key=settings.SHOPPING_CAR_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\") conn.hmset(car_key,car_dict) ret.data=\"添加成功!\"

except PricePolicyInvalid as e: ret.code=2001 ret.error=e.msg

except ObjectDoesNotExist as e: #捕捉课程不存在的异常 ret.code = 2001

ret.error = \"课程不存在\" except Exception as e: ret.code=1001

ret.error=\"添加失败\" return Response(ret.dict)

#删

def delete(self,request,*args,**kwargs): '''

购物车中删除课程 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse() try:

course_id_list=request.data.get(\"courseids\")

key_list=[settings.SHOPPING_CAR_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): '''

修改课程的价格策略 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse() try:

#1.获取价格策略ID和课程ID

course_id=int(request.data.get(\"courseid\")) policy_id=int(request.data.get(\"policyid\"))

#2.拼接课程的key

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

if not self.conn.exists(key): ret.code= 1002

ret.error=\"购物车不存在此课程\" return Response(ret.dict)

#3.在redis中获取所有价格策略:

policy_dict=json.loads(str(self.conn.hget(key,'policy'),encoding='utf-8')) print(policy_dict)

if str(policy_id) not in policy_dict: ret.code=1003

ret.error=\"价格策略不合法\" return Response(ret.dict)

#4.在购物车中修改该课程的默认价格策略 self.conn.hset(key,'default_policy',policy_id) ret.data=\"修改成功\" except Exception as e: ret.code=1001

ret.error=\"课程修改失败\" return Response(ret.dict)

#查

def get(self,request,*args,**kwargs): '''

查看购物车中所有的商品 :param request: :param args: :param kwargs: :return: '''

ret=BaseResponse() try:

current_user_id=request.auth.user_id

key_match=settings.SHOPPING_CAR_KEY%(current_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=\"1001\" ret.error=\"获取失败\" return Response(ret.dict)

View Code

因篇幅问题不能全部显示,请点此查看更多更全内容