0.先在redis测试
# Author:Jesi
# Time : 2018/10/25 18:36import redisimport 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设置过期时间,如果长时间没有结算,那么应该把这个购物车清空。
添加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:18import jsonimport redis
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet,ViewSetMixinfrom rest_framework.response import Response
from django_redis import get_redis_connection #导⼊django_redisfrom 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.py
from rest_framework.authentication import BaseAuthenticationfrom api import models
from rest_framework.exceptions import AuthenticationFailedclass 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.py
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.py
SHOPPING_CAR_KEY = \"luffy_shopping_car_%s_%s\"
最后在PY⽂件中测试⼀下,看⼀下redis到底存⼊了数据没有。
通过循环,拿到了购物车的数据,表⽰添加的接⼝开发完毕!
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)
获取到的结果显⽰如下:
{
\"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
完整源码:urls.py
from django.conf.urls import url
from api.views.course import coursehostfrom api.views.user import account
from api.views.course import newspapersfrom 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 url(r'^newspapers/', newspapers.NewsPapers.as_view({\"get\": \"list\"})), url(r'^newspapers/(?P url(r'^newspapers/(?P url(r'shoppingcar/$',shoppingcar.ShoppingCarViewSet.as_view()) View Code shoppingcar.py # Author:Jesi # Time : 2018/10/26 9:18import jsonimport redis from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet,ViewSetMixinfrom rest_framework.response import Responsefrom django_redis import get_redis_connectionfrom utils.response import BaseResponsefrom api.views.auth.auth import LuffyAuthfrom api import models from django.core.exceptions import ObjectDoesNotExistfrom utils.exception import PricePolicyInvalidfrom 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 因篇幅问题不能全部显示,请点此查看更多更全内容