一、视频播放
一般来说,视频的服务要么是放到自己的服务器上,或者是依托第三方平台
比如CC视频,我们可以把视频上传到CC视频中,然后到用他的接口和方法来实现视频的服务,具体的使用要参考你所使用的第三方服务商提供的接口文档
二、 购物车接口
购物车数据放在哪?
购物车中的数据是一种临时状态,所以可以放到redis中
设计存放到redis中的数据格式
shoppingcart_用户ID{
'课程ID':{
'title':课程名,
'img':课程图片,
'default_policy':选中价格策略,
'policy':{
当前课程的所有价格策略
'policy的ID':{
{
"period":课程周期(天),比如30,
"period_display":课程周期的简写,30天==1个月,
"price": 对应的价格
}
},
........
}
},
.........
}
添加购物车
from api.utils.MyAuth import Login_token
from django_redis import get_redis_connection
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.views import APIView
from rest_framework.response import Response
from api import models
from api.utils.common import MyResponse, CommonException
import json
class Shopping(APIView):
authentication_classes = [Login_token]
conn = get_redis_connection()
def post(self, request):
'''
业务逻辑:
1. 校验课程是否存在
2. 如果课程存在,获得课程的所有价格策略
3. 从redis中取出当前登录用户的购物车
4. 循环构造出价格策略大字典
5. 判断价格策略是否合法,不再字典中,就不合法
6. 判断传入的课程id是否在购物车中,在就更新,不在就添加
7. 写入redis
:param request:
{"course_id":"1","policy_id":"3"}
课程ID course_id:'',
价格策略ID policy_id:''
:return:
'''
response = MyResponse()
course_id = request.data.get('course_id')
policy_id = request.data.get('policy_id')
# 1.校验课程是否存在,不存在则会抛出异常,被ObjectDoesNotExist接收
try:
course = models.Course.objects.get(pk=course_id)
# 2.如果课程存在,获得课程的所有价格策略
policy_all = course.price_policy.all()
# 3.从redis中取出当前登录用户的购物车
shopping_cart_byte = self.conn.get('shoppingcart_%s'% request.user.pk)
if shopping_cart_byte:
# 为了方便获取数据,转成字典
shopping_cart = json.loads(shopping_cart_byte)
else:
# 如果没有,则建立一个空字典
shopping_cart={}
# 4.循环构造出价格策略大字典
policy_dic={}
for policy in policy_all:
'''
{
"period":3,
"period_display":"3天",
"price":200
},
'''
policy_one = {
'period':policy.valid_period,
"period_display": policy.get_valid_period_dispaly(),
"price": policy.price
}
policy_dic[str(policy.pk)]=policy_one
# 5.判断价格策略是否合法, 不再字典中, 就不合法
if policy_id not in policy_dic:
# 自定义异常
raise CommonException(102,'价格策略不存在')
# 6.判断传入的课程id是否在购物车中,在就更新,不在就添加
if course_id in shopping_cart:
shopping_cart[course_id]['default_policy']=policy_id
response.msg = '更新成功'
else:
shopping_course={
'title': course.name,
'img': course.course_img,
'default_policy': policy_id,
'policy':policy_dic
}
shopping_cart[course_id] = shopping_course
response.msg = '添加成功'
# 7.写入redis
# json.dumps(shopping_cart):转成字符型才可以存储
self.conn.set('shoppingcart_%s'% request.user.pk,json.dumps(shopping_cart))
except ObjectDoesNotExist as e:
response.status=101
response.msg='课程不存在'
except CommonException as e:
response.status=e.status
response.msg=e.msg
except Exception as e:
response.status = 400
response.msg = '未知错误'
return Response(response.get_dic)
自定义异常
class CommonException(Exception):
def init(self,status,msg):
self.status=status
self.msg=msg
修改课程价格策略
def put(self, request):
response = MyResponse()
course_id = request.data.get('course_id')
policy_id = request.data.get('policy_id')
# 1.校验课程是否存在,不存在则会抛出异常,被ObjectDoesNotExist接收
try:
# 获得当前用户购物车
shopping_cart_byte = self.conn.get('shoppingcart_%s'% request.user.pk)
if shopping_cart_byte:
# 为了方便获取数据,转成字典
shopping_cart = json.loads(shopping_cart_byte)
else:
# 如果没有,则建立一个空字典
shopping_cart={}
# 检测课程
if course_id not in shopping_cart:
raise CommonException(103, '课程不存在')
# 检测价格策略
if policy_id not in shopping_cart[course_id]['policy']:
raise CommonException(102,'价格策略不存在')
# 设置shopping_cart
shopping_cart[course_id]['default_policy']=policy_id
response.msg = '更新成功'
# 写入redis
# json.dumps(shopping_cart):转成字符型才可以存储
self.conn.set('shoppingcart_%s'% request.user.pk,json.dumps(shopping_cart))
except ObjectDoesNotExist as e:
response.status=101
response.msg='课程不存在'
except CommonException as e:
response.status=e.status
response.msg=e.msg
except Exception as e:
response.status = 400
response.msg = '未知错误'
print(e)
return Response(response.get_dic)
查看购物车
def get(self, request):
response = MyResponse()
try:
shopping_cart_byte = self.conn.get('shoppingcart_%s' % request.user.pk)
if shopping_cart_byte:
shopping_cart = json.loads(shopping_cart_byte)
else:
shopping_cart = {}
response.data = shopping_cart
except ObjectDoesNotExist as e:
response.status = 101
response.msg = '课程不存在'
except Exception as e:
response.status = 400
response.msg = '未知错误'
print(e)
return Response(response.get_dic)
删除购物车数据
def delete(self, request):
response = MyResponse()
course_id = request.data.get('course_id')
try:
shopping_cart_byte = self.conn.get('shoppingcart_%s'% request.user.pk)
if shopping_cart_byte:
# 为了方便获取数据,转成字典
shopping_cart = json.loads(shopping_cart_byte)
else:
# 如果没有,则建立一个空字典
shopping_cart={}
shopping_cart.pop(course_id,None)
response.msg = '删除成功'
self.conn.set('shoppingcart_%s'% request.user.pk,json.dumps(shopping_cart))
except Exception as e:
response.status = 400
response.msg = '未知错误'
print(e)
return Response(response.get_dic)
三、优惠券分析
优惠券分两大类,三种:
全站优惠券
满减券
立减券
打折券
课程优惠券
满减券
立减券
打折券
class Coupon(models.Model):
"""优惠券生成规则"""
name = models.CharField(max_length=64, verbose_name="活动名称")
brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍")
coupon_type_choices = ((0, '立减券'), (1, '满减券'), (2, '折扣券'))
coupon_type = models.SmallIntegerField(choices=coupon_type_choices, default=0, verbose_name="券类型")
# 优惠券由money_equivalent_value、off_percent和minimum_consume组成
# 立减券 = money_equivalent_value
# 满减券 = money_equivalent_value + minimum_consume
# 折扣券 = off_percent
money_equivalent_value = models.IntegerField(verbose_name="等值货币", blank=True, null=True)
off_percent = models.PositiveSmallIntegerField("折扣百分比", help_text="只针对折扣券,例7.9折,写79", blank=True, null=True)
minimum_consume = models.PositiveIntegerField("最低消费", default=0, help_text="仅在满减券时填写此字段")
content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定")
content_object = GenericForeignKey('content_type', 'object_id')
quantity = models.PositiveIntegerField("数量(张)", default=1)
open_date = models.DateField("优惠券领取开始时间")
close_date = models.DateField("优惠券领取结束时间")
valid_begin_date = models.DateField(verbose_name="有效期开始时间", blank=True, null=True)
valid_end_date = models.DateField(verbose_name="有效结束时间", blank=True, null=True)
coupon_valid_days = models.PositiveIntegerField(verbose_name="优惠券有效期(天)", blank=True, null=True,
help_text="自券被领时开始算起")
date = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "31. 优惠券生成规则"
def str(self):
return "%s(%s)" % (self.get_coupon_type_display(), self.name)
class CouponRecord(models.Model):
"""优惠券发放、消费纪录"""
# 跟优惠券生成规则是一对多的关系
coupon = models.ForeignKey("Coupon", on_delete=models.CASCADE)
number = models.CharField(max_length=64)
# 跟user什么关系?一对多,一个用户有多张优惠券,一张优惠券只能给一个用户
user = models.ForeignKey("UserInfo", verbose_name="拥有者", on_delete=models.CASCADE)
status_choices = ((0, '未使用'), (1, '已使用'), (2, '已过期'))
status = models.SmallIntegerField(choices=status_choices, default=0)
get_time = models.DateTimeField(verbose_name="领取时间", help_text="用户领取时间")
used_time = models.DateTimeField(blank=True, null=True, verbose_name="使用时间")
class Meta:
verbose_name_plural = "32. 优惠券发放、消费纪录"
def str(self):
return '%s-%s-%s' % (self.user, self.number, self.status)