Django REST framework+Vue 打造生鲜超市(九) 十、购物车、订单管理和支付功能

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

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")

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极客生活

数据分析python技能之es数据提取

Elasticsearch 公司的产品栈非常全面,打通数据采集,传递,存储,展示,而且部署简单快速,半天时间就可以搭建一套完整的POC出来。

1923
来自专栏lgp20151222

关于一次性的数据输入,excel字符串连接保存到服务器还是CRUD?

开发中遇到个问题,线下一个紧急的活动,给一个excel的文件,要把里面的一次性的数据放进活动里面,说真的几百几千个数据啊,手写进数据库不是更麻烦了吗?

1262
来自专栏逸鹏说道

一个粗心的Bug,JSON格式不规范导致AJAX错误

一、事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里。 当时正在联调一个项目,由于后端没有提供数据...

3594
来自专栏何俊林

Android 插件化和热修复知识梳理

本文来自IAM四十二授权发布,IAM四十二的简书地址:http://www.jianshu.com/u/c6f7cfa366d9 概述 在Android开发中...

4319
来自专栏逸鹏说道

07. Web大前端时代之:HTML5+CSS3入门系列~H5 地理位置

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 定位类型 IP ...

4484
来自专栏Albert陈凯

Spark开发电商日志分析用户行为聚合功能练习下面开始搭建开发环境注意Task表中最后一个列task_param中,Json的StartDate和EndDate需要设置成今天,因为mock数据的时候,

项目介绍 ? 项目介绍 电商网站的各种用户行为进行分析 访问首页 → 点击商品 → 添加购物车 → 结算 访问首页 → 输入关键词 → 点击商品列表 → 点击...

5119
来自专栏花叔的专栏

实践并解读最新的小程序码生成方式

花叔一看到这个新特性时就开始着手研究这特性怎么应用,经过一轮测试,终于有点成绩,来看看花叔的研究成果,希望对大家有用。

4226
来自专栏王清培的专栏

.NET应用架构设计—表模块模式与事务脚本模式的代码编写

阅读目录: 1.背景介绍 2.简单介绍表模块模式、事务脚本模式 3.正确的编写表模块模式、事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架...

21210
来自专栏极客猴

爬虫实战二:爬取电影天堂的最新电影

前面两篇文章介绍 requests 和 xpath 的用法。我们推崇学以致用,所以本文讲解利用这两个工具进行实战。

1382
来自专栏华仔的技术笔记

iOS应用架构谈 网络层设计方案

网络层在一个App中也是一个不可缺少的部分,工程师们在网络层能够发挥的空间也比较大。另外,苹果对网络请求部分已经做了很好的封装,业界的AFNetworking也...

3949

扫码关注云+社区

领取腾讯云代金券