django项目中购物车的实现
对于做项目而言,最重要的是分析清楚自己负责模块的思路,确定思路后,把每一步实现的步骤确定后,根据步骤,去实现代码,测试。
购物车的逻辑:
登录用户可以添加购物车,未登陆用户页可以添加到购物车
登陆用户的保存user.id sku_id count selected 保存在redis中,以hash和set两种方式保存
未登陆用户保存sku_id count selectd 保存再cookie中
cart = {
sku_id:{count:5,selected:True},
sku_id:{count:1,selected:True},
}
1、项目中的settings.py中设置
# Application definition
CORS_ALLOW_CREDENTIALS = True #允许携带cookie访问
2、项目中的settings.py添加数据库redis
CACHES = {
"cart": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/4",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
3、创建子应用cart
在终端的虚拟环境下进入到工程中,执行以下命令
>>>(py3_django_38) python@ubuntu:~/Desktop/shopping_mall/mall/apps$ python ../manage.py startapp cart
4、在工程的settings.py中添加apps
INSTALLED_APPS = ['cart.apps.CartConfig'] #本质是让工程加载子应用的配置,实质就是子应用配置的路径,可以根据路径查询到子应用的配置
5、在cart/views.py中添加视图
import pickle
import base64 from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView from cart.serializers import CartSerializer class CartAPIView(APIView): '''
因为我们APIView在我们调用http方法前会进行认证
我们的token过期或者伪造的化,会直接返回401
这个不符合业务逻辑
我们的业务逻辑应该是token过期或伪造的化应该认为是一个匿名用户
匿名用户的购物车数据可以放在cookie中
对于我们编程而言,应该能够先进入http方法,等验证用户信息是,再验证
''' def perform_authentication(self, request):
pass '''
当用户点击添加购物车按钮的时候
登陆用户需要将token sku_id count 选中状态提交给后端
未登陆用户需要将 sku_id count 选中状态提交给后端 后端:1、接收数据(sku_id count selected)
2、验证数据 (验证商品的id是否有对应的商品,商品的个数)
3、获取数据
4、得到用户信息
5、根据用户的信息进行判断
6、登陆用户保存再redis中
6.1、链接redis
6.2、保存hash set
6.3返回响应
7、未登录用户 保存再cookie中
7.1 先读取cookie信息
7.2 判断是否有购物车信息
如果有 加密处理
如果没有
7.3 判断这个商品是否再cookie中
如果在,累加数据
如果不在则直接添加
7.4将购物车数据进行加密处理
7.5返回响应 ''' #添加购物车
def post(self,request): # #因为我们是在需要判断的时候再去判断用户的信息 ,所以需要对用户的信息进行异常捕获
# try:
# user = request.user
#
# except Exception as e:
# user = None
# pass
#1、后端接收数据
data = request.data #2、验证数据(对应id是否有商品,商品的个数)
serializer = CartSerializer(data=data) serializer.is_valid(raise_exception=True) #获取数据
sku_id = serializer.validated_data.get('sku_id')
count = serializer.validated_data.get('count')
selected = serializer.validated_data.get('selected') #4、得到用户的信息
try:
user = request.user
except Exception as e:
user = None #5、根据用户的信息进行判断
# request.user.is_authenticated
if user is not None and user.is_authenticated:
#user不为空,而且是认证用户
#6、登陆用户保存在redis中
#6.1链接redis
redis_conn = get_redis_connection('cart')
#6.2保存数据
#hash
#具体的存储方式需要查看文档才能确定
# redis_conn.hset('cart_%s'%user.id,sku_id,count)
# hash没有进行累加操作 应该累加
# hincrby 累加操作 累加数据可以是正数页可以是负数
# redis_conn.hincrby('cart_%s'%user.id,sku_id,count)
'''
管道
管道是基础redis类的子类,他为在单个请求中向服务器缓冲多个命令提供技术支持
他们可以用于通过减少客户端和服务器之间来回的tcp数据包数量来显著提高命令组的性能
A、创建管道
pl = redis_conn.pipeline()
B、将redis指令添加到管道中
pl.hincrby('cart_%s'%user.id,sku_id,count) C、执行管道
pl.execute() '''
pl = redis_conn.pipeline() pl.hincrby('cart_%s'%user.id,sku_id,count) #set
if selected:
# redis_conn.sadd('cart_selected_%s'%user.id,sku_id)
pl.sadd('cart_selected_%s'%user.id,sku_id) pl.execute()
#6.3返回数据
return Response(serializer.data) else:
#7、未登录用户保存在cookie中
#7.1 先读取cookie信息
cookie_str = request.COOKIES.get('cart')
#7.2判断是否有购物车信息
if cookie_str is not None:
#如果有,则是加密数据
#7.2.1 将加密后的数据进行解码
decode = base64.b64decode(cookie_str) #7.2.2 将二进制转化为字典
cookie_cart = pickle.loads(decode) else:
#如果没有,则定义一个空字典
cookie_cart = {} #7.3判断这个商品是否在cookie中
if sku_id in cookie_cart: #如果在 则累加,
#先获取之前的数据
original_count = cookie_cart[sku_id]['count'] count += original_count #如果不在,则直接添加
cookie_cart[sku_id] = {
'count':count,
'selected':selected
} #将购物车进行加密处理
#7.4.1 将字典转化为bytes类型
dumps = pickle.dumps(cookie_cart)
#7.4.2 对bytes类型进行编码
encode = base64.b64encode(dumps) #7.5返回响应
response = Response(serializer.data) #为啥要解码呢 将二进制转化为字符串
response.set_cookie('cart',encode.decode()) return response
6、添加序列化器
cart/serializers.py
from rest_framework import serializers class CartSerializer(serializers.Serializer): sku_id = serializers.IntegerField(label='sku_id', required=True, min_value=1)
count = serializers.IntegerField(label='数量', required=True, min_value=1)
selected = serializers.BooleanField(label='是否勾选', required=False, default=True) def validate(self, attrs):
#判断商品是否存在
sku_id = attrs['sku_id']
try:
sku = SKU.objects.get(pk=sku_id)
except SKU.DoesNotExist:
raise serializers.ValidationError('商品不存在') #判断库存是否充足
count = attrs['count']
if sku.stock < count:
raise serializers.ValidationError('库存不足') return attrs
7、添加路由
7.1在工程的urls.py中添加
urlpatterns = [
url(r'^cart/',include('cart.urls')),
]
7.2在cart/urls.py中添加
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$',views.CartAPIView.as_view()),
]
8、添加html和js代码
添加购物车的功能已实现,查询后期再更新
django项目中购物车的实现的更多相关文章
- [翻译]在Django项目中添加谷歌统计(Google Analytics)
原文:<Google Analytics tracking code into Django projects, the easy way> 对我来说,制作一个可扩展的Django应用随时 ...
- Django项目中使用Redis
Django项目中使用Redis DjangoRedis 1 redis Redis 是一个 key-value 存储系统,常用于缓存的存储.django-redis 基于 BSD 许可, 是一个使 ...
- 擦他丫的,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了!
擦 ,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了! 问题在于我使用的谷歌浏览器,默认使用了缓存,导致每次访问同一个url时,都返回的是缓存里面的东西.通过谷歌 ...
- django 项目中使用多数据库 multiple databases
假如在一个django项目中使用到了不只一个数据库, 其实这在大一点的工程中很常见,比如主从库 那么会涉及到如下一些东西 1, 定义 在settings中的DATABASE中定义会使用到的数据,比如除 ...
- django 项目中的 favicon.ico 处理
django 项目中的 favicon.ico 处理 (django == 2.0.6) 1. 引入模块: from django.views.generic.base import Redirec ...
- Django项目中模板标签及模板的继承与引用【网站中快速布置广告】
Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...
- Django项目中"expected str, bytes or os.PathLike object, not list"错误解决:
对于这个错误,也在于自己对django基础的掌握不是很牢固,忽略了MEDIA_ROOT的类型是string,而不是list. 错误的写法: MEDIA_ROOT = [ os.path.join(BA ...
- django项目中遇到要实现定时任务
django项目中遇到要实现定时任务,所以选用了简单易用的django-crontab插件. 1.安装 django-crontab pip install django-crontab 2.定时要执 ...
- 【技术博客】JWT的认证机制Django项目中应用
开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. JWT的认证机制Django项目中应用 这篇技术博客基于软 ...
随机推荐
- activiti-explore(activiti5.17) 替换数据库
http://blog.csdn.net/xiangwangye66/article/details/46943301
- 【JAVA】servlet执行流程
servlet执行流程 客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将request.respon ...
- NPM 报错--fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module
fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module 解决 ...
- JAVA写接口傻瓜(?)教程(一)
当一个安卓开发人员/微信小程序开发者想做点什么的时候,如果他发现没有合适的接口,那么单机安卓.本地数据库emmm.没了接口就好像老人没了拐杖.盲人没了墨镜,完全可以称得上是举步维艰.生活艰难到需要自己 ...
- Qt 适合做界面
确实感觉的Qt的界面开发相比MFC方便了许多,不用为设计和实现窗口烦恼.不需要太细研究界面的实现,从Qt自带的例子中就能轻松学习和应用.在界面开发上Qt的实用比MFC前进了许多.做C++开发不管怎样如 ...
- 关于scrapy
Scrapy安装 1,Pip install wheel 2,pip install 复制路径+文件名Twisted-18.7.0-cp36-cp36m-win_amd64.whl 3,Pip ins ...
- Android NDK pthreads详细使用
这个pthread.h文件可以在NDK环境里创建子线程,并对线程能够做出互斥所.等待.销毁等控制. 写这个博客的原因是我要写如何使用FFmpeg播放视频,因为同时需要播放音频和视频所以需要开启线程,并 ...
- Kali Linux Vmware虚拟机(新手)安装
准备工作: 1.安装VMware workstation 软件 2.下载好kali linux 的ios系统文件 3.打开电脑的虚拟化支持(Intel VT-x/EPT或AMD-V/RVI(V)) 虚 ...
- K2百家讲坛 | 越秀地产:K2为房企数字化转型带来更多可能
随着数字化经济时代的到来,房地产行业逐渐形成了新的竞争和市场格局,房企要在此背景下实现稳步发展,需要由原本的粗放式管理逐渐向集团性管理.精细化管控转变,这对房企的经营发展战略和业务管理方式都提出了不小 ...
- nopcommerce 4.1 core 插件 相关1
nop中 插件机制是比较值得学习的: Nop 插件学习: 1. 项目里面的生成必须是采用 直接编辑项目文件,参考nop原本的项目文件 动态加载插件的方法-mvc3 参考: using System.L ...