购物车全选

1. 后端接口设计

请求方式 : PUT /cart/selection/

请求参数: JSON 或 表单

参数 类型 是否必须 说明
selected bool 是否全选,true表示全选,false表示取消全选

返回数据:JSON

返回值 类型 是否必须 说明
message str ok

2. 后端实现

在carts/serializers.py中新建序列化器

class CartSelectAllSerializer(serializers.Serializer):
    """
    购物车全选
    """
    selected = serializers.BooleanField(label='全选')

在carts/views.py中新建视图

class CartSelectAllView(APIView):
    """
    购物车全选
    """
    def perform_authentication(self, request):
        """
        重写父类的用户验证方法,不在进入视图前就检查JWT
        """
        pass

    def put(self, request):
        """
        购物车全选
        """
        # 1. 获取勾选状态并进行校验
        serializer = CartSelectAllSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        selected = serializer.validated_data['selected']

        # 2. 获取user
        try:
            user = request.user
        except Exception:
            user = None

        # 3. 设置购物车中商品全部为勾选
        if user and user.is_authenticated:
            # 3.1 如果用户已登录,设置redis购物车中商品全部为勾选
            redis_conn = get_redis_connection('cart')
            cart_key = 'cart_%s' % user.id

            # 获取用户购物车所有商品id
            sku_ids = redis_conn.hkeys(cart_key)

            # 将sku_ids添加到用户购物车勾选商品数据中
            cart_selected_key = 'cart_selected_%s' % user.id
            if selected:
                redis_conn.sadd(cart_selected_key, *sku_ids)
            else:
                redis_conn.srem(cart_selected_key, *sku_ids)

            return Response({'message': 'OK'})
        else:
            response = Response({'message': 'OK'})
            # 3.2 如果用户未登录,设置cookie购物车中商品全部为勾选
            cookie_cart = request.COOKIES.get('cart')

            if not cookie_cart:
                return Response

            if cookie_cart:
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))

            if not cart_dict:
                return response

            for sku_id in cart_dict.keys():
                cart_dict[sku_id]['selected'] = selected

            # 4. 返回应答,全选成功
            cookie_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart', cookie_data, expires=constants.CART_COOKIE_EXPIRES)
            return response

3. 前端实现

修改js/cart.js文件

    // 购物车全选
    on_selected_all: function(){
            var selected = !this.selected_all;
            axios.put(this.host + '/cart/selection/', {
                    selected
                }, {
                    responseType: 'json',
                    headers:{
                        'Authorization': 'JWT ' + this.token
                    },
                    withCredentials: true
                })
                .then(response => {
                    for (var i=0; i<this.cart.length;i++){
                        this.cart[i].selected = selected;
                    }
                })
                .catch(error => {
                    console.log(error.response.data);
                })
        },