一、购物车逻辑
吧价格策略+课程id存入redis,传入token进行认证,检验课程是否存在, 价格策略是否合适,也可以存在数据库,我们是存在redis里的, 为什么选择存在redis? - 临时状态(之后购物车是需要删除的),这是小公司,为了节省空间, 可以用redis定时删除 - 价格策略有可能经常修改 使用redis主要就是避免对数据库进行重复操作,我们的redis买的是阿里云16G的服务 用户发送POST请求,创建购物车中的一条商品: token 课程ID 价格策略ID 展示购物车页面发送:GET请求 获取redis中的所有课程 删除课程:DELETE 修改课程:PATCH #用POstman运行请求测试
二、代码实现
url.py
urlpatterns = [ url(r'^shopping_car/$', shopping_car.ShoppingCarView.as_view()), ]
views.py
from rest_framework.views import APIView from rest_framework.response import Response from django.core.exceptions import ObjectDoesNotExist from api import models from api.utils.auth.api_view import AuthAPIView from api.utils.exception import PricePolicyDoesNotExist from pool import POOL import json from django.conf import settings import redis CONN = redis.Redis(connection_pool=POOL) class ShoppingCarView(AuthAPIView,APIView): def get(self,request,*args,**kwargs): """ 查看购物车 :param request: :param args: :param kwargs: :return: """ course = CONN.hget(settings.LUFFY_SHOPPING_CAR,request.user.id) course_dict = json.loads(course.decode('utf-8')) return Response(course_dict) def post(self,request,*args,**kwargs): """ 获取课程ID和价格策略ID,放入redis :param request: :param args: :param kwargs: :return: """ ret = {'code':1000,'msg':None} try: course_id = request.data.get('course_id') price_policy_id = request.data.get('price_policy_id') # 1. 获取课程 course_obj = models.Course.objects.get(id=course_id) # 2. 获取当前课程的所有价格策略: id, 有效期,价格 price_policy_list = [] flag = False price_policy_objs = course_obj.price_policy.all() for item in price_policy_objs: if item.id == price_policy_id: flag = True price_policy_list.append({'id':item.id, 'valid_period':item.get_valid_period_display(),'price':item.price}) if not flag: raise PricePolicyDoesNotExist() # 3. 课程和价格策略均没有问题,将课程和价格策略放到redis中 # 课程id,课程图片地址,课程标题,所有价格策略,默认价格策略 course_dict = { 'id':course_obj.id, 'img':course_obj.course_img, 'title':course_obj.name, 'price_policy_list':price_policy_list, 'default_policy_id':price_policy_id } # a. 获取当前用户购物车中的课程 car = {1: {,,,}, 2:{....}} # b. car[course_obj.id] = course_dict # c. conn.hset('luffy_shopping_car',request.user.id,car) nothing = CONN.hget(settings.LUFFY_SHOPPING_CAR,request.user.id) if not nothing: data = {course_obj.id: course_dict} else: data = json.loads(nothing.decode('utf-8')) data[course_obj.id] = course_dict CONN.hset(settings.LUFFY_SHOPPING_CAR,request.user.id, json.dumps(data)) except ObjectDoesNotExist as e: ret['code'] = 1001 ret['msg'] = "课程不存在" except PricePolicyDoesNotExist as e: ret['code'] = 1002 ret['msg'] = "价格策略不存在" except Exception as e: ret['code'] = 1003 ret['msg'] = "添加购物车异常" return Response(ret) def delete(self, request, *args, **kwargs): res = { "state": 10000, "data": None, "msg": None } course_id = request.data.get("course_id") try: cart = json.loads(CONN.hget(settings.SHOPPING_CART_KEY, request.user.id).decode("utf-8")) cart.pop(str(course_id)) CONN.hset(settings.SHOPPING_CART_KEY, request.user.id, json.dumps(cart)) res["data"] = cart except AttributeError: # 用户第一次打开购物车,但是第一次打开购物车不可能走到这一步 res["state"] = 40000 res["msg"] = "非法操作,请检查数据" except KeyError: # 购物车已空或者删除不存在的商品,正常流程不会走到这一步 res["state"] = 40000 res["msg"] = "非法操作,请检查数据" return JsonResponse(res) def patch(self, request, *args, **kwargs): # 局部更新与post功能重复,建议直接发post请求 res = ResData(msg="局部更新与post功能重复,请直接发post请求") return JsonResponse(res) def options(self, request, *args, **kwargs): return JsonResponse({ "state": 10000, "data": None, "msg": None })
三、认证
可以通过继承来做
views.py
from api.utils.auth.auth_view import AuthForView
AuthForView
from api.utils.auth.auth_token import LuffyCityTokenAuth class AuthForView(object): authentication_classes = [LuffyCityTokenAuth, ]
LuffyCityTokenAuth
import datetime from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from api import models class LuffyCityTokenAuth(BaseAuthentication): keyword = "token" model = models.UserAuthToken valid_period = 86400000 # 86400000毫秒=24小时 # valid_period = 100000 # 86400000毫秒=24小时 res = { "state": 40000, "data": { "back_url": None, # "auth_url": None }, "msg": None } def authenticate(self, request): self.res["data"]["back_url"] = request.path_info token = request.query_params.get(self.keyword, None) if not token: self.res["msg"] = "请登录后访问" raise AuthenticationFailed(self.res) auth = self.model.objects.filter(token=token).first() if not auth: self.res["msg"] = "认证失败,请重新登录!" raise AuthenticationFailed(self.res) token_exist_period = self.get_token_exist_period(auth) if token_exist_period > self.valid_period: self.res["msg"] = "认证已过期,请重新登录!" raise AuthenticationFailed(self.res) return auth.user, auth def get_token_exist_period(self, auth): now = datetime.datetime.now() return now.timestamp() - auth.created.timestamp()
浙公网安备 33010602011771号