一  基本功能

-添加购物车
  -详见代码
-修改课程价格策略
  -put或者patch
{"course_id": "1", "policy_id": "1"}
-查看购物车
-删除购物车数据
-购物车数据放在哪?
  -放到redis中,不需要创建mysql的表来存储数据了

二  实现代码

2.1相关表单建立

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericRelation
# Create your models here. # class CourseType(models.Model): class UserInfo(models.Model):
name = models.CharField(max_length=64)
pwd = models.CharField(max_length=32) class Token(models.Model):
user = models.OneToOneField(to=UserInfo)
token = models.CharField(max_length=64) class Category(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=64)
class Course(models.Model):
"""专题课程"""
# unique=True 唯一性约束 name = models.CharField(max_length=128, unique=True)
course_img = models.CharField(max_length=255)
brief = models.TextField(verbose_name="课程概述", max_length=2048) level_choices = ((0, '初级'), (1, '中级'), (2, '高级'))
# 默认值为1 ,中级
level = models.SmallIntegerField(choices=level_choices, default=1)
pub_date = models.DateField(verbose_name="发布日期", blank=True, null=True)
period = models.PositiveIntegerField(verbose_name="建议学习周期(days)", default=7)
# help_text 在admin中显示的帮助信息
order = models.IntegerField("课程顺序", help_text="从上一个课程数字往后排") status_choices = ((0, '上线'), (1, '下线'), (2, '预上线'))
status = models.SmallIntegerField(choices=status_choices, default=0)
# 用于GenericForeignKey反向查询,不会生成表字段,切勿删除
price_policy = GenericRelation("PricePolicy")
category = models.ForeignKey(to='Category',to_field='nid',null=True) def __str__(self):
return self.name class Meta:
verbose_name_plural = "专题课" class CourseDetail(models.Model):
"""课程详情页内容"""
course = models.OneToOneField("Course", on_delete=models.CASCADE)
hours = models.IntegerField("课时")
# 课程的标语 口号
course_slogan = models.CharField(max_length=125, blank=True, null=True)
# video_brief_link = models.CharField(verbose_name='课程介绍', max_length=255, blank=True, null=True)
# why_study = models.TextField(verbose_name="为什么学习这门课程")
# what_to_study_brief = models.TextField(verbose_name="我将学到哪些内容")
# career_improvement = models.TextField(verbose_name="此项目如何有助于我的职业生涯")
# prerequisite = models.TextField(verbose_name="课程先修要求", max_length=1024)
# 推荐课程
# related_name 基于对象的反向查询,用于替换表名小写_set
recommend_courses = models.ManyToManyField("Course", related_name="recommend_by", blank=True)
teachers = models.ManyToManyField("Teacher", verbose_name="课程讲师") def __str__(self):
return "%s" % self.course class Meta:
verbose_name_plural = "课程详细" class PricePolicy(models.Model):
"""价格与有课程效期表"""
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # 关联course or degree_course
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') # course = models.ForeignKey("Course")
valid_period_choices = ((1, '1天'), (3, '3天'),
(7, '1周'), (14, '2周'),
(30, '1个月'),
(60, '2个月'),
(90, '3个月'),
(180, '6个月'), (210, '12个月'),
(540, '18个月'), (720, '24个月'),
)
valid_period = models.SmallIntegerField(choices=valid_period_choices)
price = models.FloatField()
class Meta:
unique_together = ("content_type", 'object_id', "valid_period")
verbose_name_plural = "价格策略" def __str__(self):
return "%s(%s)%s" % (self.content_object, self.get_valid_period_display(), self.price) class Teacher(models.Model):
"""讲师、导师表"""
name = models.CharField(max_length=32)
image = models.CharField(max_length=128)
brief = models.TextField(max_length=1024) def __str__(self):
return self.name class Meta: verbose_name_plural = "讲师"

2.2自定义response与Exception信息

class MyResponse():
def __init__(self):
self.status = 100
self.msg = None @property
def get_dic(self):
return self.__dict__ class CommonException(Exception):
def __init__(self,status,msg):
self.status =status
self.msg = msg

2.3登录认证组件

from rest_framework.authentication import BaseAuthentication
from api import models
from rest_framework.exceptions import AuthenticationFailed class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
ret = models.UserToken.objects.filter(token=token).first()
if ret:
# 有值说明认证通过,返回两个值
return ret.user, ret
else:
raise AuthenticationFailed('认证失败,没有登录')

2.4views

from rest_framework.views import APIView
from rest_framework.response import Response
from api import models from api.utils.commonUtils import MyResponse
from rest_framework.viewsets import ViewSetMixin
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from api.utils.MyAuth import LoginAuth
from api.utils.commonUtils import CommonException
from django_redis import get_redis_connection
import json # 需要登录之后才能操作,写一个认证组件
class ShoppingCart(APIView):
authentication_classes = [LoginAuth]
conn = get_redis_connection() def post(self, request, *args, **kwargs):
response = MyResponse()
# 课程id,价格策略id
# {"course_id": "1", "policy_id": "1"}
# 放到redis中key值 shoppingcart_userid_courseid
# 0 取出课程id,价格策略id
course_id = str(request.data.get('course_id'))
policy_id = str(request.data.get('policy_id'))
# 1 校验课程是否合法
try:
course = models.Course.objects.get(pk=course_id)
# 2 获取所有价格策略(通过课程拿出所有价格策略)
policy_price_all = course.price_policy.all()
# 3 从redis中取出当前登录用户的购物车
shopping_byte = self.conn.get('shoppingcart_%s' % request.user.pk)
if shopping_byte:
shopping_cart = json.loads(shopping_byte)
else:
shopping_cart = {}
# 循环构造出价格策略大字典
policy = {}
for policy_price in policy_price_all:
'''
{
"period":3,
"period_display":"3天",
"price":200
},
'''
policy_one = {
'period': policy_price.pk,
'period_display': policy_price.get_valid_period_display(),
'price': policy_price.price
}
policy[str(policy_price.pk)] = policy_one
# 判断价格策略是否合法,不再字典中,就不合法
if policy_id not in policy:
# 不合法
raise CommonException(102, '价格策略不合法,你不是人')
# 判断传入的课程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
} # 添加到购物车
shopping_cart[course_id] = shopping_course
response.msg = '添加成功'
# 写入redis
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(str(e))
return Response(response.get_dic) def put(self,request,*args,**kwargs):
response=MyResponse()
# 0 取出课程id,价格策略id
course_id = str(request.data.get('course_id'))
policy_id = str(request.data.get('policy_id'))
try:
shopping_byte = self.conn.get('shoppingcart_%s' % request.user.pk)
if shopping_byte:
shopping_cart = json.loads(shopping_byte)
else:
shopping_cart = {}
if course_id not in shopping_cart:
raise CommonException(102,'要修改的课程不存在')
course_detail=shopping_cart.get(course_id)
if policy_id not in course_detail['policy']:
raise CommonException(103, '价格策略不合法')
course_detail['default_policy']=policy_id
response.msg='修改成功'
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(str(e))
return Response(response.get_dic) def get(self,request,*args,**kwargs):
response=MyResponse()
try:
shopping_byte = self.conn.get('shoppingcart_%s' % request.user.pk)
if shopping_byte:
shopping_cart = json.loads(shopping_byte)
else:
shopping_cart = {}
response.data=shopping_cart except Exception as e:
response.status = 400
response.msg = '未知错误'
print(str(e))
return Response(response.get_dic) def delete(self, request, *args, **kwargs):
response=MyResponse()
course_id=request.data.get('course_id')
try:
shopping_byte = self.conn.get('shoppingcart_%s' % request.user.pk)
if shopping_byte:
shopping_cart = json.loads(shopping_byte)
else:
shopping_cart = {}
shopping_cart.pop(course_id,None)
self.conn.set('shoppingcart_%s' % request.user.pk, json.dumps(shopping_cart))
except Exception as e:
response.status = 400
response.msg = '未知错误'
print(str(e))
return Response(response.get_dic)

2.5redis配置

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": 1000}
# "PASSWORD": "123",
}
}
}

django-luffycity-购物车接口的更多相关文章

  1. Django day 37 网站视频的播放,购物车接口,优惠券表分析

    一:网站视频的播放, 二:购物车接口, 三:优惠券表分析

  2. 初识Django —Python API接口编程入门

    初识Django —Python API接口编程入门 一.WEB架构的简单介绍 Django是什么? Django是一个开放源代码的Web应用框架,由Python写成.我们的目标是用Python语言, ...

  3. python3.8.0 Django 开发后端接口api 部署到 Linux Centos7上

    经历了两天的时候终于把本地使用python3 django开发的接口API部署到服务器上了,还是记录一下,以免之后忘记,哈哈 注意一点,就是,centos7是基于python2的,我这边默认的是pyt ...

  4. RESTful规范与django编写restful接口

    一.什么是RESTful规范 ①REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” ②REST从资 ...

  5. Django提供后台接口的跨域问题

    --> Django跨域 当使用Django仅用来开发后端接口,为前端提供JSON数据的时候,不可避免的要接受前端的POST请求.虽然Django以其强大易用的特定使用很广泛,但在跨域问题上却让 ...

  6. Django model对象接口

    Django model查询 # 直接获取表对应字段的值,列表嵌元组形式返回 Entry.objects.values_list('id', 'headline') #<QuerySet [(1 ...

  7. django添加REST_FRAMEWORK 接口浏览

    1.安装rest_framework pip install djangorestframework  2.配置rest_framework ## 将rest_framework加入项目app列表 I ...

  8. django开发后台接口error 10053/10054

    初学Django,开发完接口之后访问post请求的接口遇到error10053和10054,查阅很多资料没有找到具体的原因. 在这里记录下我遇到这两个报错的原因和解决方案: get请求取请求参数:su ...

  9. 接口自动化平台搭建(二),搭建django项目与接口自动化平台的由来与功能特征

    1.创建django项目 a.使用命令创建,安装完django之后就有django-admin命令了,执行命令创建即可,命令如下: django-admin startproject my_djang ...

  10. 使用Django开发简单接口:文章增删改查

    目录 1.一些准备工作 安装django 创建django项目 创建博客应用(app) 2.models.py 3.django admin 登录 创建超级用户 4.修改urls.py 5.新增文章接 ...

随机推荐

  1. 基于html5和jquery的篮球跳动游戏

    今天给大家分享一款基于html5和jquery的篮球跳动游戏.这款实例和之前分享的HTML5重力感应小球冲撞动画类似.用鼠标拖动篮球,篮球在页面上跳动,可在演示中看下效果.效果图如下: 在线预览    ...

  2. Oracle拉出在sqlserver建表的语句

    我们将Oracle数据同步到sqlserver时,是先得在sqlserver端建表的. 复杂的字段我们不同步,就仅仅考虑以下四种数据类型. Oracle到SQLServer做的映射: int -> ...

  3. httpoxy 漏洞预警及修复方案

    影响范围 PHP.Go.Python等开启CGI(Client)模式的脚本语言 Language 环境依赖 HTTP Client PHP php-fpmmod_php Guzzle 4+Artax ...

  4. qtcreator 中文乱码

    qt输入法不能用,ui中不能显示中文,开发板不能显示中文,这几个一直困扰这我,网上查找资料,在代码中添加各种支持,都没有解决问题.今天刚好解决了,记录于此. 参考链接 http://blog.163. ...

  5. mysql存储过程,获取指定数据库的某个表的字段信息

    DROP PROCEDURE IF EXISTS Proc; DELIMITER //CREATE PROCEDURE Proc(database_name varchar(50),table_nam ...

  6. Tomcat6连接数设置:permsize

    Tomcat6默认配置,在后台一阵全点击服务器就报废了,查了一下就要是PERMSIZE默认值过小造成(16-64) TOMCAT_HOME/bin/catalina.sh 添加一行:JAVA_OPTS ...

  7. jboss eap 6.4 部署 从weblogic迁移

    从weblogic10.3像jboss 6.4项目迁移,遇到的一些问题: 因为使用weblogic可以自定义公共的war包库,在使用jboss中,也采取项目依赖公共库的方式: 1.jboss中使用公共 ...

  8. 工作流JBPM_day01:1-说明_MyProcessDesigner_流程设计器

    工作流JBPM_day01:1-说明 先只做请假功能,怎么做? (请假可以和考勤整合到一起) 1,银行(拿号---叫号---办理) 2,餐馆(点菜---上菜---结账) 3,网购(下订单--配送--收 ...

  9. Entity Framework 学习建议及教学PPT

    EntityFramework(EF)是微软平台主流的数据存取技术.为了给学生介绍这一技术,我制作了三讲Entity Framework 5.0教学PPT,包括相应源码及示例数据库. 教学内容主要参考 ...

  10. 主线程不能执行耗时的操作,子线程不能更新Ui

    在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 在看方法之前看一下Android中消息机制: 引用 Message:消息 ...