购物车设计思路

0.先在redis测试

# Author:Jesi # Time : 2018/10/25 18:36
import redis import 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设置过时时间,若是长时间没有结算,那么应该把这个购物车清空。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:18
import json import redis from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet,ViewSetMixin from rest_framework.response import Response from django_redis import get_redis_connection #导入django_redis from 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.pydjango

from rest_framework.authentication import BaseAuthentication from api import models from rest_framework.exceptions import AuthenticationFailed class 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.pyjson

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.pyapi

SHOPPING_CAR_KEY = "luffy_shopping_car_%s_%s"

 

最后在PY文件中测试一下,看一下redis到底存入了数据没有。服务器

经过循环,拿到了购物车的数据,表示添加的接口开发完毕!app

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)

获取到的结果显示以下:ide

{ "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

 完整源码:post

urls.py测试

from django.conf.urls import url from api.views.course import coursehost from api.views.user import account from api.views.course import newspapers from 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<pk>\d+)/$', coursehost.CourseViewSet.as_view({"get": "retrieve"})), url(r'^newspapers/', newspapers.NewsPapers.as_view({"get": "list"})), url(r'^newspapers/(?P<pk>\d+)/$', newspapers.NewsPapers.as_view({"get": "retrieve"})), url(r'^newspapers/(?P<pk>\d+)/agree/$', newspapers.AgreeView.as_view({'post': 'post'})), url(r'shoppingcar/$',shoppingcar.ShoppingCarViewSet.as_view())
View Code

shoppingcar.pyurl

# Author:Jesi # Time : 2018/10/26 9:18
import json import redis from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet,ViewSetMixin from rest_framework.response import Response from django_redis import get_redis_connection from 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(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
相关文章
相关标签/搜索