(项目)生鲜超市(九)
十、购物车,订单管理和支付功能
1、购物车功能
在trade/serializers.py中编写购物车序列化的代码:
1 class ShopCartSerialzier(serializers.Serializer): 2 user = serializers.HiddenField( 3 default=serializers.CurrentUserDefault() 4 ) 5 nums = serializers.IntegerField(required=True, label='数量', min_value=1, 6 error_messages={ 7 "min_value": "商品数量不能小于一", 8 "required": "请选择购买数量" 9 }) 10 # goods是一个外键,可以通过这方法获取goods object中所有的值 Serializer必须指定queryset对象,ModelSerializer不需要指定 11 goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all()) 12 13 # Serializer没有save方法,必须重写create方法 14 def create(self, validated_data): # validated_data是已经处理过的数据 15 # 获取当前用户,view中获取用户self.request.user serializer中获取用户self.context["request"].user 16 user = self.context["request"].user 17 nums = validated_data["nums"] 18 goods = validated_data["goods"] 19 20 existed = ShoppingCart.objects.filter(user=user, goods=goods) 21 # 购物车有记录,数量+nums 22 if existed: 23 existed = existed[0] 24 existed.nums += nums 25 existed.save() 26 else: 27 # 没有记录,添加到购物车 28 existed = ShoppingCart.objects.create(**validated_data) 29 30 return existed 31 32 # Serializer没有update方法,所以重写Update方法, 添加购物车数量 33 def update(self, instance, validated_data): 34 # 修改商品数量 35 instance.nums = validated_data["nums"] 36 instance.save() 37 return instance
在trade/views.py中编写购物车接口:
1 class ShoppingCartViewSet(viewsets.ModelViewSet): 2 """ 3 购物车功能 4 list: 5 获取购物车详情 6 create: 7 加入购物车 8 delete: 9 删除购物记录 10 """ 11 12 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 13 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 14 serializer_class = ShopCartSerialzier 15 16 # 把商品id传回去 17 lookup_field = 'goods_id' 18 19 def get_queryset(self): 20 return ShoppingCart.objects.filter(user=self.request.user)
注册url:
1 router.register(r'shopcarts', ShoppingCartViewSet, base_name='shopcarts') # 购物车
购物车中可以看商品详情,需要写一个商品详情的serializer,在view中需要动态设置serializer:
1 class ShopCartDetailSerializer(serializers.ModelSerializer): 2 # 一个购物车对应一个商品 3 goods = GoodsSerializer(many=False, read_only=True) 4 class Meta: 5 model = ShoppingCart 6 fields = ('goods', 'nums')
完善购物车接口,动态选择serializer:
1 class ShoppingCartViewSet(viewsets.ModelViewSet): 2 """ 3 购物车功能 4 list: 5 获取购物车详情 6 create: 7 加入购物车 8 delete: 9 删除购物记录 10 """ 11 12 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 13 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 14 15 # 把商品id传回去 16 lookup_field = 'goods_id' 17 18 def get_serializer_class(self): 19 if self.action == 'list': 20 return ShopCartDetailSerializer 21 else: 22 return ShopCartSerializer 23 24 def get_queryset(self): 25 return ShoppingCart.objects.filter(user=self.request.user)
2、订单功能
用户添加商品到购物车,点击购物车结算,填上地址留言,结算生成订单,在会员中心我的订单里面,可以看到订单列表,点订单可以看到订单的详细信息,首先完成订单的序列化:
1 class OrderGoodsSerializer(serializers.ModelSerializer): 2 # 订单内的商品 3 goods = GoodsSerializer(many=False) 4 5 class Meta: 6 model = OrderGoods 7 fields = "__all__" 8 9 10 class OrderDetailSerializer(serializers.ModelSerializer): 11 # goods字段需要嵌套一个OrderGoodsSerializer 12 goods = OrderGoodsSerializer(many=True) 13 14 class Meta: 15 model = OrderInfo 16 fields = "__all__" 17 18 19 class OrderSerializer(serializers.ModelSerializer): 20 user = serializers.HiddenField( 21 default=serializers.CurrentUserDefault() 22 ) 23 # 生成订单的时候这些不用post 24 pay_status = serializers.CharField(read_only=True) 25 trade_no = serializers.CharField(read_only=True) 26 order_sn = serializers.CharField(read_only=True) 27 pay_time = serializers.DateTimeField(read_only=True) 28 nonce_str = serializers.CharField(read_only=True) 29 pay_type = serializers.CharField(read_only=True) 30 31 # 生成订单号 32 def generate_order_sn(self): 33 # 格式:当前时间+userid+随机数 34 random_ins = Random() 35 order_sn = '{time_str}{userid}{ranstr}'.format(time_str=time.strftime("%Y%m%d%H%M%S"), 36 userid=self.context["request"].user.id, 37 ranstr=random_ins.randint(10, 99)) 38 return order_sn 39 40 def validate(self, attrs): 41 # validate中添加order_sn,然后在view中就可以save 42 attrs['order_sn'] = self.generate_order_sn() 43 return attrs 44 45 class Meta: 46 model = OrderInfo 47 fields = "__all__"
在views.py中完成订单的接口:
1 class OrderViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin, 2 viewsets.GenericViewSet): 3 """ 4 订单管理 5 list: 6 获取个人订单 7 delete: 8 删除订单 9 create: 10 新增订单 11 """ 12 13 permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) 14 authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) 15 16 def get_serializer_class(self): 17 if self.action == "retrieve": 18 return OrderDetailSerializer 19 return OrderSerializer 20 21 def get_queryset(self): 22 return OrderInfo.objects.filter(user=self.request.user) 23 24 # 在提交订单还需要将购物车中的商品保存到OrderGoods中,然后清空购物车 25 def perform_create(self, serializer): 26 order = serializer.save() 27 28 # 获取购物车中的所有商品,将商品添加到订单中 29 shop_carts = ShoppingCart.objects.filter(user=self.request.user) 30 for shop_cart in shop_carts: 31 order_goods = OrderGoods() 32 order_goods.goods = shop_cart.goods 33 order_goods.goods_num = shop_cart.nums 34 order_goods.order = order 35 order_goods.save() 36 37 # 清空购物车 38 shop_cart.delete() 39 40 return order
注册url:
1 router.register(r'orders', OrderViewSet, base_name='orders') # 订单
不要忘了修改Vue中的host,然后在前端测试添加商品到购物车,然后点击结算生成订单,在个人中心新中有订单信息。