1. 程式人生 > >(專案)生鮮超市(九)

(專案)生鮮超市(九)

十、購物車,訂單管理和支付功能

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,然後在前端測試新增商品到購物車,然後點選結算生成訂單,在個人中心新中有訂單資訊。