1. 程式人生 > >Django+Vue打造購物網站(八)

Django+Vue打造購物網站(八)

購物車、訂單管理和遠端除錯

新增商品到購物車

trade/serializers.py

from rest_framework import serializers

from goods.models import Goods
from trade.models import ShoppingCart


class ShopCartSerializer(serializers.Serializer):
    # 獲取當前登入的使用者
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    nums = serializers.IntegerField(required=True, label="數量", min_value=1,
                                    error_messages={
                                        "min_value": "商品數量不能小於一",
                                        "required": "請選擇購買數量"
                                    })
    # 這裡是繼承Serializer,必須指定queryset物件,如果繼承ModelSerializer則不需要指定
    # goods是一個外來鍵,可以通過這方法獲取goods object中所有的值
    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())

    # 繼承的Serializer沒有save功能,必須寫一個create方法
    def create(self, validated_data):
        # validated_data是已經處理過的資料
        # 獲取當前使用者
        # view中:self.request.user;serizlizer中:self.context["request"].user
        user = self.context["request"].user
        nums = validated_data["nums"]
        goods = validated_data["goods"]

        existed = ShoppingCart.objects.filter(user=user, goods=goods)
        # 如果購物車中有記錄,數量+1
        # 如果購物車車沒有記錄,就建立
        if existed:
            existed = existed[0]
            existed.nums += nums
            existed.save()
        else:
            # 新增到購物車
            existed = ShoppingCart.objects.create(**validated_data)

        return existed

trade/views.py

from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from trade.models import ShoppingCart
from trade.serializers import ShopCartSerializer
from utils.permissions import IsOwnerOrReadOnly


class ShoppingCartViewset(viewsets.ModelViewSet):
    """
    購物車功能
    list:
        獲取購物車詳情
    create:
        加入購物車
    delete:
        刪除購物記錄
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    serializer_class = ShopCartSerializer

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)

urls.py

# 配置購物車的url
router.register(r'shopcarts', ShoppingCartViewset, base_name="shopcarts")

修改購物車數量

Serializer繼承BaseSerializer,但是Seriazer中並沒有重新update方法,所有新增一個update方法

trade/serializers.py

    def update(self, instance, validated_data):
        # 修改商品數量
        instance.nums = validated_data["nums"]
        instance.save()
        return instance

在view中要把商品id傳過去

lookup_field = "goods_id"

vue和購物車介面聯調

trade/serializers.py

class ShopCartDetailSerializer(serializers.ModelSerializer):
    '''
    購物車商品詳情資訊
    '''
    # 一個購物車對應一個商品
    goods = GoodsSerializer(many=False, read_only=True)
    class Meta:
        model = ShoppingCart
        fields = ("goods", "nums")

trade/views.py
需要動態選擇serializer

    def get_serializer_class(self):
        if self.action == 'list':
            return ShopCartDetailSerializer
        else:
            return ShopCartSerializer

訂單管理介面

使用者新增商品到購物車,點去購物車結算,填上地址留言,結算生成訂單,在會員中心我的訂單裡面,可以看到訂單列表,點訂單可以看到訂單的詳細資訊。

trade/serializers.py

# 訂單中的商品
class OrderGoodsSerialzier(serializers.ModelSerializer):
    goods = GoodsSerializer(many=False)

    class Meta:
        model = OrderGoods
        fields = "__all__"


# 訂單商品資訊
# goods欄位需要巢狀一個OrderGoodsSerializer
class OrderDetailSerializer(serializers.ModelSerializer):
    goods = OrderGoodsSerialzier(many=True)

    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)

    def generate_order_sn(self):
        # 生成訂單號
        # 當前時間+userid+隨機數
        from random import Random
        random_ins = 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_ins.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__"

trade/views.py

class OrderViewset(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin,
                   viewsets.GenericViewSet):
    """
    訂單管理
    list:
        獲取個人訂單
    delete:
        刪除訂單
    create:
        新增訂單
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    serializer_class = OrderSerializer

    # 動態配置serializer
    def get_serializer_class(self):
        if self.action == "retrieve":
            return OrderDetailSerializer
        return OrderSerializer

    # 獲取訂單列表
    def get_queryset(self):
        return OrderInfo.objects.filter(user=self.request.user)

    # 在訂單提交儲存之前還需要多兩步步驟,所以這裡自定義perform_create方法
    # 1.將購物車中的商品儲存到OrderGoods中
    # 2.清空購物車
    def perform_create(self, serializer):
        order = serializer.save()
        # 獲取購物車所有商品
        shop_carts = ShoppingCart.objects.filter(user=self.request.user)
        for shop_cart in shop_carts:
            order_goods = OrderGoods()
            order_goods.goods = shop_cart.goods
            order_goods.goods_num = shop_cart.nums
            order_goods.order = order
            order_goods.save()
            # 清空購物車
            shop_cart.delete()
        return order

urls.py

# 配置訂單的url
router.register(r'orders', OrderViewset, base_name="orders")

遠端除錯

第三方登入和支付,都需要有伺服器(公網IP),我們可以用pycharm去遠端除錯伺服器程式碼

配置安全組,開啟ssh,資料傳輸等可以參考之前的部署