vue+django2.0.2-rest-framework 生鲜项目


 一、购物车功能

 1、实现购物车获取购物车商品列表信息、添加购物车商品数量、删除购物车商品

1)trade/serializer.py:序列化购物车数据

 几点说明:

  1. serializers.Serializer中没有get(list)、post(create)方法,需要自定义。
  2. views.py中获取当前用户 代码操作:self.request.user  ; serializers.py中,要获取当前用户,代码:self.context["request"].user ,存放于context当中。
  3. goods是一个外键,之前我们序列化goods商品时,goods/serializers.py中有用到序列化的CategorySerializer来展示外键相关信息,一般用list方法访问时使用这种方式展示所需要的详细信息,不需要展示商品详情时不这么做。在购物车model中,因为使用了联合唯一(goods、nums),不允许我们同一个goods+nums添加多个,否则会报错,所以我们不用耦合性较高的ModelSerializers,而是用Serializers。外键处理则使用DRF提供的PrimaryKeyRelatedField字段处理:
    goods = serializers.PrimaryKeyRelatedField(required=True, queryset=Goods.objects.all())
    在serializers.Serializer中,‘queryset=Goods.objects.all()’这句是必须要写的,获取所有的商品数据,是个querysets集合,
    在serializers.ModelSerializer中,该语句是这样:goods = serializers.PrimaryKeyRelatedField(required=True, many=True,read_only),
    两句代码效果是一样的,第二句是因为内部有model,会自己映射,所以不用添加queryset搜查所有数据。
  4. goods = GoodsSerializer():使用序列化这种方式,会将提交的某goods商品所有信息以序列化形式都展示出来,需要全部填写才能提交
    goods = serializers.PrimaryKeyRelatedField:是个querysets集合,只会显示model中(__str__)return的字段信息,比如商品的名称(name),不需要我们操作。
    购物车需要获取的只是goods中的商品名称,故用第二种,不能用第一种序列化的方式。
  5. serializers.Serializer中,create()、update()两个方法,当需要用到时,需要我们在serializers中重载,否则会报错:`create()` must be implemented 。
    而serializers.ModelSerializer中,系统已经简单帮我们实现了这两个方法,不需要我们重载
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)
        #如果购物车中有记录,数量+nums
        #如果购物车车没有记录,就创建
        if existed:
            existed = existed[0]
            existed.nums += nums
            existed.save()
        else:
            #添加到购物车
            existed = ShoppingCart.objects.create(**validated_data)

        return existed

 2)trade/views.py:

 重载 get_queryset 方法,只查找与当前客户相关的购物车数据

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)urls.py配置:

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

 

  vue+django2.0.2-rest-framework 生鲜项目(七)

 vue+django2.0.2-rest-framework 生鲜项目(七)


 

 上述已经完成了当前用户购物车数据获取、购物车商品创建,接下来我们来实现购物车商品数据更新:更新商品数量

  更新数据,需要用到update () 方法,因此,我们需要在serializers中重载该方法:

1)trade/serializer.py下的 ShopCartSerializer 添加:

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

 2)在view中要把商品id传过去:

 因为更新单条数据,或者删除单条数据,需要用到商品id。

 lookup_field = "goods_id"

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
    lookup_field = "goods_id"
    
    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)
ShoppingCartViewset

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-10
相关资源
相似解决方案