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",
}
}
}

在settings中做配置:连接redis用

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)

购物车的逻辑代码, 取从redis获取,拿也是从redis中拿

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':''
#....课程详情的数据
}
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

支付功能实现

drf框架之 路飞学城(第二天)的更多相关文章

  1. drf框架使用之 路飞学城(第一天)

    1. 路飞学城第一天: 知识点 使用的是序列化与反序列化的使用: 1.创建一个公共相应的Json方法: #创建一个公共响应的类: class LuffyResponse(): def __init__ ...

  2. 路飞学城—Python爬虫实战密训班 第二章

    路飞学城—Python爬虫实战密训班 第二章 一.Selenium基础 Selenium是一个第三方模块,可以完全模拟用户在浏览器上操作(相当于在浏览器上点点点). 1.安装 - pip instal ...

  3. django环境部署 crm和路飞学城

    环境依赖 yum install gcc patch libffi-devel python-devel zlib-devel bzip2-devel openssl-devel ncurses-de ...

  4. linux vue uwsgi nginx 部署路飞学城 安装 vue

    vue+uwsgi+nginx部署路飞学城 有一天,老男孩的苑日天给我发来了两个神秘代码,听说是和mjj的结晶 超哥将这两个代码,放到了一个网站上,大家可以自行下载 路飞学城django代码#这个代码 ...

  5. python 全栈开发,Day98(路飞学城背景,django ContentType组件,表结构讲解)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  6. 路飞学城Python-Day59(第五模块复习题)

    HTML div标签是块级标签,单独一行,可以作为其他标签的容器,没有特定含义 span是内联标签,可以作为文本内容的容器,没有特定含义 1. 查询一下对div和span标签的理解 不同的标签有自己含 ...

  7. 路飞学城Python-Day59(第五模块记录)

    HTML部分 <!DOCTYPE html> <html lang="en"> <head> <!--head标签的主要作用:文档的头部主 ...

  8. 路飞学城Python-Day53

    01-jquery的介绍 JS在做项目或者是实现功能的时候,用JS去操作DOM元素非常复杂,代码量大,重复性代码也多 多个元素使用for循环遍历也是非常麻烦的,对于JS使用来说加大了难度 jQuery ...

  9. day75:luffy:路飞学城项目后端环境搭建&Git相关知识点

    目录 1.Xadmin 1.Xadmin介绍 2.Xadmin安装 3.Xadmin的使用 2.项目环境搭建 1.外部依赖 2.依赖包安装 3.搭建项目 3.Git 4.日志配置 5.异常处理 6.创 ...

随机推荐

  1. tensorboard No graph definition files were found No scalar data was found 解决方法

    logdir后面的路径不要加引号!!!! tensorboard --logdir='D:\WorkSpace\eclipse\tf_tr\train\my_graph\' 删除引号,改为: tens ...

  2. PymongoDB_study

    import pymongo client = pymongo.MongoClient(host='localhost',port=27017)#连接数据库 #db = client.test#指定数 ...

  3. Oracle报错TNS-12532: TNS:invalid argument

    今天一个同事遇到了一个oracle问题,在数据库本机通过sqlplus登录sys用户时报TNS-12532: TNS:invalid argument,这个错误. 造成这个错误的原因主要有三个,一般排 ...

  4. java_oop_接口

    接口    难的是在系统设计里怎么样使用接口,主要在语法,不在系统架构与设计    概念    声明    语法        只有抽象方法的抽象类?可以用接口来表示,用接口来代替这样的抽象类,是因为 ...

  5. install rust

    Step 1. Trial 1 Download rustup-init.exe exec rustup-init.exe SW hangs 2. Trial 2 install rust-1.33. ...

  6. FileUpload上传

    单文件上传: ASPX: <div> <!-- 文件上传 --> <asp:FileUpload ID="FileUpload1" runat=&qu ...

  7. java中增删改查(CRUD)总结

    对于User表增删改查:1:save(保存方法)  view(查询所有记录) update(更新方法) delete(删除方法) 通过method这个参数进行判断执行不同的操作 2: 具体的实现:   ...

  8. Freescale MKL16Z1288VF4 芯片调试接口

    WDOG监视内部系统操作,并在发生故障时强制复位.它可以运行在一个独立的1 kHz低功率振荡器,具有可编程刷新窗口,以检测程序流或系统频率的偏差. 看门狗计时器保持一个时间在系统上运行,并重置它,以防 ...

  9. C# 重写Equals

    public class PerformanceRank { public int Rank { get; set; } public string Eid { get; set; } public ...

  10. Functional programming idiom

    A functional programming function is like a mathematical function, which produces an output that typ ...