开源web框架django知识总结(十九)

开源web框架django知识总结(十九)

阿尔法商城(购物车)

购物车存储方案

新建apps->carts

  • 必须是用户登录状态下,才可以保存购物车数据。
  • 用户对购物车数据的操作包括:增、删、改、查、全选等等
  • 每个用户的购物车数据都要做唯一性的标识。

1. 购物车存储方案

1.存储数据说明

  • 如何描述一条完整的购物车记录?
    • 用户,选择了两个 iPhone8 添加到了购物车中,状态为勾选
  • 一条完整的购物车记录包括:用户商品数量勾选状态
  • 存储数据:user_id、sku_id、count、selected

2.存储位置说明

  • 购物车数据量小,结构简单,更新频繁,所以我们选择内存型数据库Redis进行存储。
  • 存储位置:dev.py文件中Redis数据库 5号库
"carts": {
    # 购物车
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://192.168.42.128:6379/5",
        "OPTIONS": {
   
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },

3.存储类型说明

  • 提示:我们很难将用户、商品、数量、勾选状态存放到一条Redis记录中。所以我们要把购物车数据合理的分开存储。
  • 用户、商品、数量:hash
    • carts_user_id: {sku_id1: count, sku_id3: count, sku_id5: count, ...}
  • 勾选状态:set
    • 只将已勾选商品的sku_id存储到set中,比如,1号和3号商品是被勾选的。
    • selected_user_id: [sku_id1, sku_id3, ...]
      注释:Redis Smembers 命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。

4.存储逻辑说明

  • 当要添加到购物车的商品已存在时,对商品数量进行累加计算。
  • 当要添加到购物车的商品不存在时,向hash中新增field和value即可。

==============================================

购物车管理

添加购物车

提示:在商品详情页添加购物车使用局部刷新的效果。

1. 添加购物车接口设计和定义

1.请求方式

选项 方案
请求方法 post
请求地址 /carts/

2.请求参数:JSON

参数名 类型 是否必传 说明
sku_id int 商品SKU编号
count int 商品数量
selected bool 是否勾选

3.响应结果:JSON

字段 说明
code 状态码
errmsg 错误信息

2. 添加购物车后端逻辑实现

1.接收和校验参数 carts.views.py

import json

from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.views import View
from django_redis import get_redis_connection

from utils.views import login_required  # 注意修改导包路径
from goods.models import SKU
# Create your views here.

class CartsView(View):

 # 把sku商品加入购物车
    @method_decorator(login_required)
    def post(self, request):
        # 1、提取参数
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected', True)

        # 2、校验参数
        if not all([sku_id, count]):
            return JsonResponse({
   'code': 400, 'errmsg': '缺少参数!'})

        if not isinstance(selected, bool):
            return JsonResponse({
   'code': 400, 'errmsg': '参数有误!'})

        # 3、判断是否登陆
        user = request.user
        if user.is_authenticated:
            # 4、登陆写入redis
            conn = get_redis_connection('carts')
            # 4.1 记录sku商品数量——carts_<user_id> : {sku_id: count}
            # conn.hmset('carts_%s'%user.id, {sku_id:count}) # 我们不能使用该函数,因为他会覆盖原有数据
            conn.hincrby('carts_%s'%user.id, sku_id, amount=count) # 把sku商品数量增加count,如果不存在则新建
            # 4.2 记录选中状态——selected_<user_id> : [sku_id]
            if selected:
                conn.sadd('selected_%s'%user.id, sku_id)

            return JsonResponse({
   'code': 0, 'errmsg': 'ok'})

=========================================

展示购物车

1. 展示购物车接口设计和定义

1.请求方式

选项 方案
请求方法 GET
请求地址 /carts/

**2.请求参数:**无

3.响应结果:HTML cart.html

4.后端接口定义 carts.views.py

class CartsView(View):

    def get(self, request):
        # 0、初始化一个空字典,用于保存sku购物车数据,其格式和cookie购物车格式一样
        cart_dict = {
   } # {1: {count:xx, selected:xx}}

        user = request.user
        if user.is_authenticated:
            # 1、用户登陆,则从redis中读取sku商品信息
           pass

2. 展示购物车后端逻辑实现

1.查询Redis购物车

2.查询购物车SKU信息

3.返回响应数据

 # 展示购物车
    @method_decorator(login_required)
    def get(self, request):
        # 0、初始化一个空字典,用于保存sku购物车数据,其格式和cookie购物车格式一样
        cart_dict = {
   }  # {1: {count:xx, selected:xx}}

        user = request.user
        if user.is_authenticated:
            # 1、用户登陆,则从redis中读取sku商品信息
            conn = get_redis_connection('carts')
            # 2、sku商品数量、是否选中
            # cart_redis_dict = {b'1': b'8'}
            cart_redis_dict = conn.hgetall('carts_%s' % user.id)
            # cart_redis_selected = [b'1']
            cart_redis_selected = conn.smembers('selected_%s' % user.id) #smembers返回集合中的所有的成员。 不存在的集合 key 被视为空集合
            #将cart_redis_dict与cart_redis_selected合并
            for k, v in cart_redis_dict.items(): #字典(Dictionary) items() 函数以列表返回可遍历的(键, 值) 元组数组。
                # k: b'1'; v: b'8'
                cart_dict[int(k)] = {
   
                    'count': int(v),
                    'selected': k in cart_redis_selected  # b'1' in [b'1']返回True
                }

        cart_skus = []
        # 3、构建响应返回
        for k, v in cart_dict.items():
            # k: sku_id; v: {count:xx, selected: xx}
            sku = SKU.objects.get(pk=k)
            cart_skus.append({
   
                'id': sku.id,
                'name': sku.name,
                'count': v['count'],
                'selected': v['selected'],
                'price': sku.price,
                'default_image_url': sku.default_image_url.url,
                'amount': sku.price * v['count']
            })

        return JsonResponse({
   'code': 0, 'errmsg': 'ok', 'cart_skus': cart_skus})

==============================================

修改购物车

提示:在购物车页面修改购物车使用局部刷新的效果。

1. 修改购物车接口设计和定义

1.请求方式

选项 方案
请求方法 PUT
请求地址 /carts/

2.请求参数:JSON

参数名 类型 是否必传 说明
sku_id int 商品SKU编号
count int 商品数量
selected bool 是否勾选

3.响应结果:JSON

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主打Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值