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

1、添加商品到购物车

(1)trade/serializer.py

这里的serializer不继承ModelSerializer,是因为自己写的Serializer更加灵活,因为购物车在添加相同数据的时候,是不能报错的,而如果继承ModelSerializer ,在model.py的ShoppingCart里面需要定义unique_together,这在mixins.CreateModelMixin里的create方法的is_valid的时候,如果记录里面已经有添加记录了,在验证的时候就报错了,根本不会用到ModelSerializer 里面的create方法,这时就算我们重写ModelSerializer的create方法也是无效的。当然也可以重写mixins.CreateModelMixin里的create方法,但这样我们就不能用Serializer给我们的好处。

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则不需要指定(ModelSerializer是goods = GoodsSerializer())
#goods是一个外键,可以通过这方法获取goods object中所有的值
goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all()) #继承的Serializer没有create功能,必须写一个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
# 上面整个流程的总结概述就是,首先在view里面,调用get_serializer(data=request.data),获取ShopCartSerializer,把数据填入其中,进行is_valid()验证,这一步就是判断user(能不能获取当前用户)和nums
# (传入的值符不符合要求)。通过之后,调用perform_create(),然后运行里面的serializer.save(),.save()方法去调用我们继承的serializers.Serializer里面的create()方法,在这里也就是我们重写的那个,
# 然后就是进行各种判断,把数据保存到数据库啥的,最后把数据返回。

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

2、添加购物车数量

根据商品id搜索收藏记录在view中添加

lookup_field = "goods_id"

对购物车商品进行update操作,发现出错

是因为Serializer继承BaseSerializer,但是Serializer中并没有重载update方法,而BaseSerializer中的方法只会报错。所有添加一个update方法。这点跟Modelserializer不同,那里面已经写好了update方法。

trade/serializer.py

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

3、vue和购物车接口联调

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

(1)trade/serializer.py

class ShopCartDetailSerializer(serializers.ModelSerializer):
"""
购物车详情
"""
# goods在ShoppingCart里面是个外键
# 因为由ShopCartSerializer的create知道,一个ShopCart记录对应一个商品
# 所以many=False。这个想了好久才发现T_T
goods = GoodsSerializer(many=False, read_only=True) class Meta:
model = ShoppingCart
fields = "__all__"

(2)trade/views.py

需要动态选择serializer

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

4、订单管理接口

(1)trade/serializer.py

用户添加商品到购物车,点去购物车结算,填上地址留言,结算生成订单,在会员中心我的订单里面,可以看到订单列表,点订单可以看到订单的详细信息。

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) def generate_order_sn(self):
# 当前时间+userid+随机数
from random import Random
ramdon_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=ramdon_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.CreateModelMixin, mixins.DestroyModelMixin,
viewsets.GenericViewSet):
"""
订单管理
list:
获取个人订单
delete:
删除订单
create:
新增订单
"""
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
serializer_class = OrderSerializer def get_queryset(self):
return OrderInfo.objects.filter(user=self.request.user) # create之后还有两步,在获取了订单的序列之后,首先需要把购物车的内容添加到订单号里,还有一个是
# 将它们删除
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")

为了展示订单的详细信息,需要写一个OrderDetailSerializer

trade/serializer.py

# 订单中的商品
class OrderGoodsSerializier(serializers.ModelSerializer):
goods = GoodsSerializer(many=False) class Meta:
model = OrderGoods
fields = "__all__" # 订单商品的详细信息
# goods字段需要嵌套一个OrderGoodsSerializer
class OrderDetailSerializer(serializers.ModelSerializer):
goods = OrderGoodsSerializier(many=True) # 这里容易犯的错误就是会用GoodsSerializer,但从models里面知道,ForeignKey OrderInfo
# 的是order字段,所以related_name="goods"是在order字段里面的。 这样OrderInfo
                           # 通过"goods"反向指向OrderGoods,然后写一个关于OredrGoods的Serializer就行。
  class Meta:
    model = OrderInfo
    fields = "__all__"

Django REST framework+Vue 打造生鲜电商项目(笔记七)的更多相关文章

  1. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  2. Django REST framework+Vue 打造生鲜电商项目(笔记四)

    (PS:部分代码和图片来自博客:http://www.cnblogs.com/derek1184405959/p/8813641.html.有增删) 一.用户登录和手机注册 1.drf的token功能 ...

  3. Django REST framework+Vue 打造生鲜电商项目(笔记十)

    (from:https://www.cnblogs.com/derek1184405959/p/8877643.html  有修改) 十三.首页.商品数量.缓存和限速功能开发 首先把pycharm环境 ...

  4. Django REST framework+Vue 打造生鲜电商项目(笔记九)

    (from:http://www.cnblogs.com/derek1184405959/p/8859309.html) 十二.支付宝沙箱环境配置 12.1.创建应用 进入蚂蚁金服开放平台(https ...

  5. Django REST framework+Vue 打造生鲜电商项目(笔记三)

    (PS:转载自http://www.cnblogs.com/derek1184405959/p/8810591.html  有修改) 一.drf的过滤 (1)添加到app里面 INSTALLED_AP ...

  6. Django REST framework+Vue 打造生鲜电商项目(笔记十一)

    (form: http://www.cnblogs.com/derek1184405959/p/8886796.html 有修改) 十四.social_django 集成第三方登录 1.申请应用 进入 ...

  7. Django REST framework+Vue 打造生鲜电商项目(笔记八)

    (form:http://www.cnblogs.com/derek1184405959/p/8862569.html) 十一.pycharm 远程代码调试 第三方登录和支付,都需要有服务器才行(回调 ...

  8. Django REST framework+Vue 打造生鲜电商项目(笔记一)

    首先,这系列随笔是我个人在学习Bobby老师的Django实战项目中,记录的觉得对自己来说比较重要的知识点,不是完完整整的项目步骤过程....如果有小伙伴想找完整的教程,可以看看这个(https:// ...

  9. Django REST framework+Vue 打造生鲜电商项目(笔记六)

    (部分代码来自https://www.cnblogs.com/derek1184405959/p/8836205.html) 九.个人中心功能开发 1.drf的api文档自动生成 (1) url #d ...

随机推荐

  1. [转帖]Linux运维工程师的十个基本技能点

    Linux运维工程师的十个基本技能点 https://cloud.tencent.com/developer/article/1115068   本人是Linux运维工程师,对这方面有点心得,现在我说 ...

  2. 在CentOS7上安装OpenJDK1.8 & OracleJDK1.8

    安装OpenJDK1.8 : 1.检查当前机器是否有自带的JDK rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 2.如果没有 则跳至安装 ...

  3. 计算机网络自顶向下方法第3章-传输层 (Transport Layer).2

    3.5 面向连接的运输: TCP 3.5.1 TCP连接 TCP是因特网运输层的面向连接的可靠的运输协议. TCP连接提供全双工服务(full-duplex service). TCP连接是点对点的连 ...

  4. 三元组[01 Trie计数]

    也许更好的阅读体验 \(\mathcal{Description}\) \(\mathcal{Solution}\) 有两种方法都可以拿到满分 \(Solution\ 1\) 考虑枚举\(y\) 建两 ...

  5. c++智能指针介绍_补充

    不明白我做错了什么,这几天老婆给我冷战了起来,也不给我开视频让我看娃了..哎,心累!趁着今晚的一些空闲时间来对智能指针做个补充吧. 写完上篇“智能指针介绍”后,第二天上班途中时,突然一个疑问盘踞在心头 ...

  6. 音视频入门-10-使用libyuv对YUV数据进行缩放、旋转、镜像、裁剪、混合

    * 音视频入门文章目录 * libyuv libyuv 是 Google 开源的实现各种 YUV 与 RGB 之间相互转换.旋转.缩放等的库.它是跨平台的,可在 Windows.Linux.Mac.A ...

  7. ZooKeeper学习笔记(四)——shell客户端命令操作

    ZooKeeper客户端命令行操作 启动服务端 [simon@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start 查看状态信息 Using confi ...

  8. 在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名)

    原文:在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  9. SQL Server2008分离数据库

    1.右击数据库 2.Tasks 3.点击Detach 4.选取Drop Connections-->点击确定 5.开启本地数据库默认存储路径C:\Program Files\Microsoft ...

  10. win10如何安装mariadb

    一.下载.安装 1.下载mariadb(https://downloads.mariadb.org/),解压 2.进入bin目录下执行(管理员模型-powershell) .\mysqld.exe - ...