07 | Django REST framework+Vue 生鲜超市 ——购物车、订单管理
购物车
添加商品到购物车
(1)trade/serializesr.py
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
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
# 购物车 from trade.views import ShoppingCartViewset router.register(r'shopcarts', ShoppingCartViewset, base_name="shopcarts")
测试
http://127.0.0.1:8000/shopcarts/
添加购物车数量
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"
vue和购物车接口联调
购物车中可以看商品详情,需要写一个商品详情的serializer,所有在view中需要动态设置serializer
(1)trade/serializers.py
class ShopCartDetailSerializer(serializers.ModelSerializer): ''' 购物车商品详情信息 ''' # 一个购物车对应一个商品 goods = GoodsSerializer(many=False, read_only=True) class Meta: model = ShoppingCart fields = ("goods", "nums")
(2)trade/views.py 中的 ShoppingCartViewset 需要动态选择serializer
def get_serializer_class(self): if self.action == 'list': return ShopCartDetailSerializer else: return ShopCartSerializer
在对购物车进行增删改的时候我们应修改商品的库存数,对此重构其各自的方法
def perform_create(self, serializer): shop_cart = serializer.save() goods = shop_cart.goods goods.goods_num -= shop_cart.nums goods.save() def perform_destroy(self, instance): goods = instance.goods goods.goods_num += instance.nums goods.save() instance.delete() def perform_update(self, serializer): existed_record = ShoppingCart.objects.get(id=serializer.instance.id) existed_nums = existed_record.nums saved_record = serializer.save() nums = saved_record.nums-existed_nums goods = saved_record.goods goods.goods_num -= nums goods.save()
订单管理接口
(1)trade/serializers.py
用户添加商品到购物车,点去购物车结算,填上地址留言,结算生成订单,在会员中心我的订单里面,可以看到订单列表,点订单可以看到订单的详细信息。
from .models import * import time 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
from .models import * from .serializers import * from rest_framework import mixins 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")