其他分享
首页 > 其他分享> > 开源web框架django知识总结(十九)

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

作者:互联网

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

阿尔法商城(购物车)

购物车存储方案

新建apps->carts

1. 购物车存储方案

1.存储数据说明

2.存储位置说明

"carts": { # 购物车
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://192.168.42.128:6379/5",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },

3.存储类型说明

4.存储逻辑说明

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

购物车管理

添加购物车

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

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

1.请求方式

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

2.请求参数:JSON

参数名类型是否必传说明
sku_idint商品SKU编号
countint商品数量
selectedbool是否勾选

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_idint商品SKU编号
countint商品数量
selectedbool是否勾选

3.响应结果:JSON

字段说明
sku_id商品SKU编号
count商品数量
selected是否勾选

4.后端接口定义

# 修改购物车
    def put(self, request):

        user = request.user
        if user.is_authenticated:
            # 登陆,修改redis
          pass

2. 修改购物车后端逻辑实现

1.接收和校验参数

2.修改Redis购物车

# 修改购物车
    @method_decorator(login_required)
    def put(self, request):
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected', True)

        user = request.user
        if user.is_authenticated:
            # 登陆,修改redis
            conn = get_redis_connection('carts')
            conn.hmset('carts_%s' % user.id, {sku_id: count})  # 覆盖写入
            if selected:
                conn.sadd('selected_%s' % user.id, sku_id) #选中,sadd增加
            else:
                conn.srem('selected_%s' % user.id, sku_id) #未选中,srem删除
            return JsonResponse({
                'code': 0,
                'errmsg': 'ok',
                'cart_sku': {
                    'id': sku_id,
                    'count': count,
                    'selected': selected
                }
            })

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

删除购物车

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

1. 删除购物车接口设计和定义

1.请求方式

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

2.请求参数:JSON

参数名类型是否必传说明
sku_idint商品SKU编号

3.响应结果:JSON

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

4.后端接口定义

# 删除购物车
    def delete(self, request):

        user = request.user
        # 1、已登陆
        if user.is_authenticated:
          pass

2. 删除购物车后端逻辑实现

1.接收和校验参数

2.删除Redis购物车

# 删除购物车
    @method_decorator(login_required)
    def delete(self, request):
        # {"sku_id": xxx}}
        data = json.loads(
            request.body.decode()
        )
        sku_id = data.get('sku_id')

        user = request.user
        # 已登陆
        if user.is_authenticated:
            conn = get_redis_connection('carts')
            # 1.1 删除购物车哈希数据——carts_user_id :  {sku_id : count}
            # Hdel 命令用于删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。
            conn.hdel('carts_%s' % user.id, sku_id)
            # 1.2 删除集合中的sku_id
            # Srem 命令用于移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。
            #https://www.runoob.com/redis/redis-commands.html
            conn.srem('selected_%s' % user.id, sku_id)
            return JsonResponse({'code': 0, 'errmsg': 'ok'})

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

全选购物车

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

1. 全选购物车接口设计和定义

1.请求方式

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

2.请求参数:JSON

参数名类型是否必传说明
selectedbool是否全选

3.响应结果:JSON

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

4.后端接口定义

class CartSelectAllView(View):

    # 设置全选/全取消
    def put(self, request):
        # 1、获取参数
        if user.is_authenticated:
            # 已登陆:把所有的sku_id加入/删除到selected_user_id的集合中
           pass

2. 全选购物车后端逻辑实现

1.接收和校验参数

2.全选Redis购物车

class CartSelectAllView(View):

    # 设置全选/全取消
    @method_decorator(login_required)
    def put(self, request):
        # 1、获取参数
        data = json.loads(request.body.decode())
        selected = data.get("selected") # True or False

        user = request.user
        if user.is_authenticated:
            # 已登陆:把所有的sku_id加入/删除到selected_user_id的集合中
            conn = get_redis_connection('carts')
            # 1、获取用户的购物车数据
            # {b'1': b'5'}
            cart_dict = conn.hgetall('carts_%s'%user.id)
            # [b'1', b'2']
            sku_ids = cart_dict.keys()
            # 2、设置全/全取消
            if selected:
                conn.sadd('selected_%s'%user.id, *sku_ids)
            else:
                conn.srem('selected_%s'%user.id, *sku_ids)
            return JsonResponse({'code': 0, 'errmsg': 'ok'})

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

展示商品页面简单购物车

需求:用户鼠标悬停在商品页面右上角购物车标签上,以下拉框形式展示当前购物车数据。

1. 简单购物车数据接口设计和定义

1.请求方式

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

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

3.响应结果:JSON

字段说明
code状态码
errmsg错误信息
cart_skus[ ]简单购物车SKU列表
id购物车SKU编号
name购物车SKU名称
count购物车SKU数量
default_image_url购物车SKU图片

4.后端接口定义

class CartsSimpleView(View):
    """商品页面右上角购物车"""
 
    def get(self, request):
        # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            # 用户已登录,查询Redis购物车
            pass
        # 构造简单购物车JSON数据
        pass

2. 简单购物车数据后端逻辑实现

1.查询Redis购物车

2.构造简单购物车JSON数据

class CartsSimpleView(View):

    def get(self, request):
        # 读取购物车数据,把具体的sku商品信息返回
        user = request.user

        # {1: {"count":xx, "selected":xxx}}
        cart_dict = {} # 购物车数据——格式和cookie格式是一样的

        if user.is_authenticated:
            # 已登陆,从redis中读商品数据
            conn = get_redis_connection('carts')
            # {b'1': b'4'}
            carts_redis = conn.hgetall('carts_%s'%user.id)
            # [b'1']
            carts_selected = conn.smembers('selected_%s'%user.id)
            for k,v in carts_redis.items():
                # k: b'1'; v: b'4'
                cart_dict[int(k)] = {
                    'count': int(v),
                    'selected': k in carts_selected
                }


        # 构造响应数据
        cart_skus = []
        for k,v in cart_dict.items():
            # k: sku_id; v: {"count":xx, "selected":xxx}
            sku = SKU.objects.get(pk=k)
            cart_skus.append({
                'id': sku.id,
                'name': sku.name,
                'count': v['count'],
                'default_image_url': sku.default_image_url.url
            })

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

carts.urls.py

from django.urls import re_path
from .views import *

urlpatterns = [
    re_path(r'^carts/$', CartsView.as_view()),
    re_path(r'^carts/selection/$', CartSelectAllView.as_view()),
    re_path(r'^carts/simple/$', CartsSimpleView.as_view()),
]

修改前端文件

1、1.html 修改动态加载“简单购物车”显示

<!--      <div class="guest_cart fr">
            <a href="#" class="cart_name fl">我的购物车</a>
            <div class="goods_count fl" id="show_count">15</div>

            <ul class="cart_goods_show">
                <li>
                    <img src="#" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>4</div>
                </li>
                <li>
                    <img src="#" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>5</div>
                </li>
                <li>
                    <img src="#" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>6</div>
                </li>
                <li>
                    <img src="#" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>6</div>
                </li>
            </ul>
        </div>  -->
        
            <div class="guest_cart fr">
            <a href="#" class="cart_name fl">我的购物车</a>
            <div class="goods_count fl" id="show_count">[[ cart_total_count ]]</div>
            <ul class="cart_goods_show">
                <li v-for="sku in carts">
                    <img :src="sku.default_image_url" alt="商品图片">
                    <h4>[[ sku.name ]]</h4>
                    <div>[[ sku.count ]]</div>
                </li>
            </ul>
            </div>

修改

标签:sku,web,selected,count,cart,购物车,开源,django,id
来源: https://blog.csdn.net/weixin_54733110/article/details/122405225