(專案)生鮮超市(九)
阿新 • • 發佈:2018-11-27
十、購物車,訂單管理和支付功能
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, 6error_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"].user16 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,然後在前端測試新增商品到購物車,然後點選結算生成訂單,在個人中心新中有訂單資訊。