zoukankan      html  css  js  c++  java
  • 【Vue+DRF 生鲜电商】购物车和订单管理(七)

    1. 购物车

    接口:http://127.0.0.1:8000/shopcarts/

    需求:

    • 添加商品到购物车
    • 购物车中所有商品信息(详情)
    • 删除购物车记录

    1.1 添加商品到购物车

    1、trade/seriliazers.py

    class ShopCartSerializer(serializers.Serializer):
        """购物车"""
        # 获取当前登录用户
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )
        nums = serializers.IntegerField(required=True, label='数量', min_value=1,
                                        error_messages={
                                            'min_value': '商品数量不能小于一',
                                            'required': '请选择购买数量'
                                        })
        # 外键,获取 goods 中所有值,必须指定 queryset,继承 ModelSerializer 无需指定
        goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())
        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M")
    
        def create(self, validated_data):
            """
            serializers.Serializer 没有 save() 需要重写 create
            :param validated_data:已处理过的数据(前端提交的数据)
            :return:
            """
            # 获取当前用户
            user = self.context['request'].user
            nums = validated_data['nums']
            goods = validated_data['goods']
    
            # 查询数据库,若有记录(表示添加到购物车,该商品),数量 + nums,否则就添加到购物车
            existed = ShoppingCart.objects.filter(user=user, goods=goods)
    
            # 数量增加
            if existed:
                existed = existed[0]
                existed.nums += nums
                existed.save()
            else:
                # 添加到购物车
                existed = ShoppingCart.objects.create(**validated_data)
    
            return existed
    
        def update(self, instance, validated_data):
            """更新购物车,修改数量"""
            instance.nums = validated_data['nums']
            instance.save()
            return instance
    

    这里之所以采用继承 Serializer 而不是 ModelSerializer,是因为 ModelSerializer 的 creat() 方法会之前创建一条新的记录,当用户将同一商品多次添加到购物车时应该只需数量变化,而不是重写创建一条新的购物车记录,所以需要重写 create() 方法。

    2、trade/views.py

    class ShoppingCartViewSet(viewsets.ModelViewSet):
        """
        购物车功能:
        list:获取购物车详情
        create:加入购物车
        delete:删除购物车记录
        """
        serializer_class = ShopCartSerializer
        permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
        authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    
        # 商品 ID,用于购物车更新(update() 商品数量)
        lookup_field = "goods_id"
    
        def get_queryset(self):
            """获取当前用户购物车列表"""
            return ShoppingCart.objects.filter(user=self.request.user)
    

    3、配置路由 MxShop/urls.py

    router.register(r'shopcarts', ShoppingCartViewSet, basename='shopcarts')  # 购物车
    

    1.2 获取购物车商品详情

    接口:

    # 获取所有商品信息:get
    http://127.0.0.1:8000/shopcarts/
    
    # 单独获取某个商品详情:get
    http://127.0.0.1:8000/shopcarts/1/
    

    1、trade/serializers.py

    class ShopCartDetailSerializer(serializers.ModelSerializer):
        """购物车中商品详情"""
        # 一个购物车对应一个商品.
        goods = GoodsSerializer(many=False, required=True)
    
        class Meta:
            model = ShoppingCart
            fields = ('goods', 'nums')
    

    2、trade/views.py

    class ShoppingCartViewSet(viewsets.ModelViewSet):
        ....
        def get_serializer_class(self):
            """动态选择 serializer"""
            if self.action == 'list':
                return ShopCartDetailSerializer
            else:
                return ShopCartSerializer
    

    动态选择 serializer,当添加或删除购物车商品时:ShopCartSerializer,获取购物车商品详情(列表)时:ShopCartDetailSerializer

    2. 订单管理

    接口地址:http://127.0.0.1:8000/orders/

    需求分析:

    • 用户添加商品到购物车,点击结算
    • 填上地址留言(必须),结算(提交)订单
    • 会员中心可查看所以的订单列表,点击单个订单可查看订单详细信息

    支持:创建订单、获取个人订单(列表、详情)、删除订单

    1、trade/serializers.py

    class OrderGoodsSerializer(serializers.ModelSerializer):
        """订单中的商品"""
        goods = GoodsSerializer(many=False)
    
        class Meta:
            model = OrderGoods
            fields = '__all__'
    
    
    class OrderDetailSerializer(serializers.ModelSerializer):
        """
        订单中商品详细信息
        """
        # goods字段需要嵌套一个OrderGoodsSerializer
        goods = OrderGoodsSerializer(many=True)
        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M")
    
        class Meta:
            model = OrderInfo
            fields = '__all__'
    
    
    class OrderSerializer(serializers.ModelSerializer):
        """订单"""
        user = serializers.HiddenField(
            default=serializers.CurrentUserDefault()
        )
    
        # 生成订单时,不需 post以下数据
        pay_status = serializers.CharField(read_only=True)
        trade_no = serializers.CharField(read_only=True)
        order_sn = serializers.CharField(read_only=True)
        pay_time = serializers.DateTimeField(read_only=True)
        nonce_str = serializers.CharField(read_only=True)
        pay_type = serializers.CharField(read_only=True)
    
        add_time = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M")
    
        def generate_order_sn(self):
            """
            生成订单号:当前时间+userid+随机数
            :return:
            """
            from random import Random
            random_str = Random()
            order_sn = "{time_str}{userid}{ranstr}".format(time_str=time.strftime("%Y%m%d%H%M%S"),
                                                           userid=self.context['request'].user.id,
                                                           ranstr=random_str.randint(10, 99))
            return order_sn
    
        def validate(self, attrs):
            """validate 中添加 order_sn,然后再 view 中就可以 save"""
            attrs['order_sn'] = self.generate_order_sn()
            return attrs
    
        class Meta:
            model = OrderInfo
            fields = '__all__'
    

    三个 serializer

    • OrderGoodsSerializer:订单中商品(OrderGoods
    • OrderDetailSerializer:订单中商品详细信息(OrderInfo
    • OrderSerializer:订单(OrderInfo

    前端 vue 页面中需要提交的信息只有 订单留言、订单金额、收货地址、签收人、联系电话,其他诸如 订单号、支付状态、交易号等不需要在前端提交

    流程:表单字段验证通过后,validate() 中调用 generate_order_sn() 生成订单号,并将其保存到 attrs 字典中,之后 view 视图 save() 保存,订单创建成功。

    2、trade/views.py

    class OrderViewSet(viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.ListModelMixin, mixins.DestroyModelMixin,
                       mixins.RetrieveModelMixin):
        """
        订单相关
        list:获取个人订单
        create:创建订单
        delete:删除订单
        """
        serializer_class = OrderSerializer
        permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
        authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    
        def get_serializer_class(self):
            # 订单详情
            if self.action == 'retrieve':
                return OrderDetailSerializer
            else:
                return OrderSerializer
    
        def perform_create(self, serializer):
            """
            提交订单之前步骤
                1、将购物车中商品保存到 OrderGoods
                2、清空购物车
            :param serializer:
            :return:
            """
            order = serializer.save()
            # 获取购物车中所有商品
            shop_carts = ShoppingCart.objects.filter(user=self.request.user)
            for shop in shop_carts:
                order_goods = OrderGoods()
                order_goods.goods = shop.goods
                order_goods.goods_num = shop.nums
                order_goods.order = order
                order_goods.save()
    
                # 清空购物车
                shop.delete()
    
            return order
    
        def get_queryset(self):
            return OrderInfo.objects.filter(user=self.request.user)
    

    保存之前将购物车中商品保存到 OrderGoods 中,另外就是清空购物车。

    3、配置路由 MxShop/urls.py

    router.register(r'orders', OrderViewSet, basename='orders')  # 订单
    

  • 相关阅读:
    104.Maximum Depth of Binary Tree
    103.Binary Tree Zigzag Level Order Traversal
    102.Binary Tree Level Order Traversal
    101.Symmetric Tree
    100.Same Tree
    99.Recover Binary Search Tree
    98.Validate Binary Search Tree
    97.Interleaving String
    static静态初始化块
    serialVersionUID作用
  • 原文地址:https://www.cnblogs.com/midworld/p/13629732.html
Copyright © 2011-2022 走看看