• Django REST framework+Vue 打造生鲜超市(九)


    目录

    生鲜超市(一)    生鲜超市(二)    生鲜超市(三)   

    生鲜超市(四)    生鲜超市(五)    生鲜超市(六)   

    生鲜超市(七)    生鲜超市(八)    生鲜超市(九)   

    生鲜超市(十)    生鲜超市(十一)    生鲜超市(十二)    生鲜超市(十三)   

    代码下载

    github

    教程

    学习自慕课网-前端vue结合后端DjangoFramework的在线生鲜超市 

    十、购物车、订单管理和支付功能

     10.1.添加商品到购物车

    (1)trade/serializer.py

    # trade/serializer.py
    __author__ = 'derek'
    
    from .models import ShoppingCart
    from rest_framework import serializers
    from goods.models import Goods
    
    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

    (2)trade/views.py

    # trade/views.py
    
    from rest_framework import viewsets
    from rest_framework.permissions import IsAuthenticated
    from utils.permissions import IsOwnerOrReadOnly
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework.authentication import SessionAuthentication
    from .serializers import ShopCartSerializer
    from .models import ShoppingCart
    
    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

    (3)配置url

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

     10.1.添加购物车数量

    Serializer继承BaseSerializer,但是Seriazer中并没有重新update方法,所有添加一个update方法

    trade/serializer.py

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

    在view中要把商品id传过去

     lookup_field = "goods_id"

    10.3.vue和购物车接口联调

    购物车中可以看商品详情,需要写一个商品详情的serializer,所有在view中需要动态设置serializer

    (1)trade/serializer.py

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

    (2)trade/views.py

    需要动态选择serializer

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

    10.4.订单管理接口

    (1)trade/serializer.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__"

    (2)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

    (3)配置url

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

     
     
     
  • 相关阅读:
    使用ABP构建WebAPI的心得
    修改andriod模拟器的IMEI,IMSI,手机号,SIM卡号
    Abp框架下 Area中新建Layout报错的问题
    通过Roslyn构建自己的C#脚本 资料记录
    EF5 CodeFirst 修改主键自增属性
    Oracle字段类型及存储(一)
    ArcMap之等值面
    街景初看
    转:oracle中schema指什么
    OSGI起程一——确定目标
  • 原文地址:https://www.cnblogs.com/gaidy/p/12107279.html
Copyright © 2020-2023  润新知