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,数据传输等可以参考之前的部署