1.第二天的项目是用户购物的数据存入到购物车中,这样保存的数据是存放在redis中
1. 首先先配置redis的数据库链接:
#注意, 数据从redis中获取到的内容,最原始的是二进制形式的数据,想要使用就需要json.loads下 不然无法使用!记住
# redis配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "123", } } }
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from api import models class LoginAuth(BaseAuthentication): def authenticate(self, request): token=request.GET.get('token') ret=models.Token.objects.filter(key=token).first() if ret: return ret.user,token else: raise AuthenticationFailed('您没有登录,请先登录')
from rest_framework.response import Response from rest_framework.views import APIView from api import models from api.utils.commonutils import LuffyResponse from api.utils.commonutils import CommonException from api.luffyserializers import Courseserializers from api.luffyserializers import CoursesDetailSerializers from rest_framework.viewsets import ViewSetMixin from django.core.exceptions import ObjectDoesNotExist from django_redis import get_redis_connection import json from api.utils.MyAuth import LoginAuth #购物车需要登录之后才能操作(认证组件) class ShoppingView(APIView): authentication_classes=[LoginAuth] conn=get_redis_connection() def post(self,request): response=LuffyResponse() try: course_in_id=request.data.get('course_id') policy_in_id=request.data.get('policy_id') # 1 查询课程是否存在 course=models.Course.objects.get(pk=course_in_id) #2 获取所有价格策略 policy_list=course.price_policy.all() #3 取出当前用户购物车的数据 shopping_cart_dic_bytes=self.conn.get('shopping_card_%s'%request.user.id) #json可以loadsbytes格式 shopping_cart_dic=json.loads(shopping_cart_dic_bytes) if shopping_cart_dic_bytes else {} #注意,从redis中获取数据的是json形式的 # if shopping_cart_dic_bytes: # shopping_cart_dic=json.loads(shopping_cart_dic_bytes) # else: # shopping_cart_dic={} #4 循环价格策略 policy_dict={} for policy in policy_list: policy_dict[str(policy.pk)]={ 'period':policy.valid_period, 'period_display':policy.get_valid_period_display(), 'price':policy.price } #5 校验价格策略是否是该课程的价格策略 if policy_in_id not in policy_dict: raise CommonException('你是爬虫,价格策略不合法') #6 构造购物车的字典 # shopping_cart_dic[str(course.pk)] shopping_cart_dic[course_in_id]={ 'title':course.name, 'img':course.course_img, 'default_policy':policy_in_id, 'policy':policy_dict } #7 存入redis self.conn.set('shopping_card_%s'%request.user.id,json.dumps(shopping_cart_dic)) #使用的是字符串形式存入redis中,= response.msg='加入购物车成功' except CommonException as e: response.status = 102 response.msg = e.msg except ObjectDoesNotExist as e: response.status = 101 response.msg = '您要加入购物车的课程不存在' except Exception as e: response.status=105 response.msg=str(e) return Response(response.get_dic) def get(self,request): #注意这里的获取数据是通过redis来获取得到的 response = LuffyResponse() shopping_cart_dic_bytes = self.conn.get('shopping_card_%s' % request.user.id) shopping_cart_dic = json.loads(shopping_cart_dic_bytes) if shopping_cart_dic_bytes else {} response.data=shopping_cart_dic response.msg='查询成功' return Response(response.get_dic) def delete(self,request): #传入的数据格式{"course_id":"1"} course_in_id=request.data.get('course_id') response = LuffyResponse() shopping_cart_dic_bytes = self.conn.get('shopping_card_%s' % request.user.id) #获取是那个用户, 并给这个用户反序列化拿到字典形式的数据 shopping_cart_dic = json.loads(shopping_cart_dic_bytes) if shopping_cart_dic_bytes else {} #从反序列化后的字典 并踢出用户提交出来的数据 shopping_cart_dic.pop(course_in_id) #保存到redis中 self.conn.set('shopping_card_%s' % request.user.id, json.dumps(shopping_cart_dic)) response.msg = '删除成功' return Response(response.get_dic) def put(self,request): course_in_id=request.data.get('course_id') #课程ID policy_in_id=request.data.get('policy_id') #价格策略ID response = LuffyResponse() try: shopping_cart_dic_bytes = self.conn.get('shopping_card_%s' % request.user.id) #获取用户购物车内的数据注意是二进制形式 shopping_cart_dic = json.loads(shopping_cart_dic_bytes) if shopping_cart_dic_bytes else {} #取出该课程所有的价格策略 policy=shopping_cart_dic[course_in_id]['policy'] if policy_in_id not in policy: raise CommonException('传入的价格策略非法,你可能是爬虫') shopping_cart_dic[course_in_id]['default_policy']=policy_in_id #保存到redis中 self.conn.set('shopping_card_%s' % request.user.id, json.dumps(shopping_cart_dic)) response.msg='修改成功' except CommonException as e: response.status = 102 response.msg = e.msg except Exception as e: response.status=105 response.msg=str(e) return Response(response.get_dic)
from rest_framework.response import Response from rest_framework.views import APIView from api import models from api.utils.commonutils import LuffyResponse from api.utils.commonutils import CommonException from api.luffyserializers import Courseserializers from api.luffyserializers import CoursesDetailSerializers from rest_framework.viewsets import ViewSetMixin from django.core.exceptions import ObjectDoesNotExist from django_redis import get_redis_connection import datetime import json from api.utils.MyAuth import LoginAuth import time #结算中心 class PaymentView(APIView): conn=get_redis_connection() authentication_classes=[LoginAuth] def post(self,request): #{"course_list":[{"course_id":"1","policy_id":"1"},{"course_id":"2","policy_id":"2"}]} response = LuffyResponse() course_in_list=request.data.get('course_list') try: # 1 定义结算中心的字典,定义全局优惠券的字典 payment_dict_userid = {} global_coupon_dict = { "coupon": {}, "default_coupon": 0 } #2 拿到购物车,循环取出传入的课程id,判断是否在购物车中,不在直接抛异常 shopping_cart_dic_bytes = self.conn.get('shopping_card_%s' % request.user.id) # json可以loadsbytes格式 shopping_cart_dic = json.loads(shopping_cart_dic_bytes) if shopping_cart_dic_bytes else {} for course_in in course_in_list: course_in_id=course_in.get('course_id') if course_in_id not in shopping_cart_dic: raise CommonException('要结算的课程不合法,不在购物车中') #3 构造单个课程详情的字典,把购物车中的当前课程,update到该字典中 course_detail = { 'coupon': {}, 'default_coupon':'0' #....课程详情的数据 } course_detail.update(shopping_cart_dic[course_in_id]) #4 将该课程详情,加入到结算中心 payment_dict_userid[course_in_id]=course_detail #5 一次性查出当前用户的所有优惠券信息(用户为当前用户,状态为未使用,优惠券起始时间小于当前时间,优惠券结束时间大于当前时间) #获取当前时间 ctime = datetime.datetime.today().strftime('%Y-%m-%d') print(ctime) #查询此人所有可用优惠券 coupon_list = models.CouponRecord.objects.filter( user=request.user, status=0, coupon__valid_begin_date__lte=ctime, coupon__valid_end_date__gte=ctime, ) #6 循环所有优惠券 for item in coupon_list: #7 构造出单个优惠券的空字典,拿到优惠券类型(1立减 2 满减 3折扣),拿到优惠券id,拿到该优惠券绑定的课程id(有可能为空) coupon_detail = {} #优惠券类型 coupon_type=item.coupon.coupon_type #优惠券id coupon_id=item.pk #该优惠券绑定的课程id(根据这个字段判断是全站优惠券还是课程优惠券) course_id=item.coupon.object_id #8 构造单个优惠券字典,将数据填充进去 coupon_detail['coupon_type'] = coupon_type coupon_detail['coupon_display'] = item.coupon.get_coupon_type_display() if coupon_type == 0: # 立减券,构造出等值金额 coupon_detail['money_equivalent_value'] = item.coupon.money_equivalent_value elif coupon_type == 1: # 满减券,构造出等值金额,和最低消费金额 coupon_detail['money_equivalent_value'] = item.coupon.money_equivalent_value coupon_detail['minimum_consume'] = item.coupon.minimum_consume else: # 其他情况,构造出打折(如打八折,80) coupon_detail['off_percent'] = item.coupon.off_percent #9 判断是全站优惠券还是课程优惠券 if not course_id: #课程id为空,放到全站优惠券大字典中 global_coupon_dict['coupon'][str(coupon_id)]=coupon_detail else: #课程优惠券 coupon_course_id = str(course_id) if coupon_course_id not in payment_dict_userid: # 当前课程优惠券对应的可能如果不在结算中心字典里,continue continue # 在结算中心字典中的,对应放入到课程优惠券字段上 payment_dict_userid[str(coupon_course_id)]['coupon'][str(coupon_id)] = coupon_detail # 10讲结算中心字典和全局优惠券字典,放入redis中 self.conn.set('payment_dict_%s'%request.user.id,json.dumps(payment_dict_userid)) self.conn.set('global_coupon_dict_%s'%request.user.id,json.dumps(global_coupon_dict)) response.msg='加入结算中心成功' except CommonException as e: response.status = 102 response.msg = e.msg except Exception as e: response.status = 105 response.msg = str(e) return Response(response.get_dic) def get(self,request): response=LuffyResponse() payment_dic_bytes=self.conn.get('payment_dict_%s'%request.user.id) global_coupon_dict_bytes=self.conn.get('global_coupon_dict_%s'%request.user.id) payment_dic= json.loads(payment_dic_bytes) if payment_dic_bytes else {} global_coupon_dict= json.loads(global_coupon_dict_bytes) if global_coupon_dict_bytes else {} response.msg='查询成功' response.data={ 'payment':payment_dic, 'global_coupon':global_coupon_dict } return Response(response.get_dic) class PayFinal(APIView): conn=get_redis_connection() authentication_classes=[LoginAuth] def post(self,request): #传入的数据格式 # { # "price": 600 # "bely": 100 # } response = LuffyResponse() try: price_in = request.data.get('price') bely = request.data.get('bely') #1从结算中心拿出字典,全局优惠券字典取出来 payment_dic_bytes=self.conn.get('payment_dict_%s' % request.user.id) payment_dic=json.loads(payment_dic_bytes) if payment_dic_bytes else {} global_coupon_dic_bytes=self.conn.get('payment_dict_%s' % request.user.id) global_coupon_dic=json.loads(global_coupon_dic_bytes) if global_coupon_dic_bytes else {} price_list=[] #2 循环结算中心字典,得到课程和课程id for course_id,course_detail in payment_dic.items(): # 3取出默认价格策略,取出默认价格,取出默认优惠券id default_policy_id=course_detail['default_policy'] default_price=course_detail['policy'][default_policy_id]['price'] default_coupon_id=course_detail['default_coupon'] #4 判断如果默认优惠券不为0, # 表示使用了优惠券: # 取出默认优惠券的字典, # 调用计算价格函数得到价格,把价格放到价格列表中(后面直接用sum函数计算总价格) if default_coupon_id!=0: #使用了优惠券 default_coupon_detail=course_detail['coupon'][default_coupon_id] #调用计算价格的函数 default_price=self.account(default_price,default_coupon_detail) price_list.append(default_price) #5 取出全局默认优惠券id,根据默认优惠券id取出全局优惠券字典,调用计算价格函数得到实际支付价格 global_coupon_id=global_coupon_dic['default_coupon'] if global_coupon_id!=0: global_coupon_detail=global_coupon_dic['coupon'][str(global_coupon_id)] final_price=self.account(sum(price_list),global_coupon_detail) else: final_price=sum(price_list) #6判断贝利数大于传入的贝利数, # 用实际价格减去贝利数,如果得到结果小于0, # 直接等于0,判断最终价格和传如的价格是否相等, # 不相等抛异常 if not request.user.beli>=bely: raise CommonException('贝利数不合法') final_price=final_price-bely/10 if final_price<0: final_price=0 if final_price !=price_in: raise CommonException('传入的价格不合法') if final_price>0: #构造支付宝支付 # 拼凑支付宝url alipay = ali() # 生成支付的url query_params = alipay.direct_pay( subject="路飞学成课程", # 商品简单描述 out_trade_no="x2" + str(time.time()), # 商户订单号 total_amount=final_price, # 交易金额(单位: 元 保留俩位小数) ) pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params) response.url = pay_url except CommonException as e: response.status = 102 response.msg = e.msg except Exception as e: response.status = 105 response.msg = str(e) return Response(response.get_dic) def account(self,price,coupon_dic): # 设置总价格为price total_price = price # 取出优惠券类型 coupon_type = coupon_dic['coupon_type'] # 优惠券类型是0,立减 if coupon_type == 0: total_price = price - coupon_dic['money_equivalent_value'] ##优惠券类型是1,满减,必须大于最低消费金额 elif coupon_type == 1: if price >= coupon_dic['minimum_consume']: total_price = price - coupon_dic['money_equivalent_value'] else: raise CommonException('优惠券不满足最低使用金额') ##优惠券类型是2,直接打折 elif coupon_type == 2: total_price = price * coupon_dic['off_percent'] / 100 return total_price