You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework电商项目中购物车商品数量无法递增问题

问题背景

在基于Django REST Framework的电商项目中,期望用户重复添加同一商品至购物车时,Items模型的quantity字段自动递增1(默认值为1),但当前实现触发错误:Exception Value:'QuerySet' object has no attribute 'quantity'。

相关代码如下:

models.py

class Cartlist(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateField(auto_now_add=True)
    class Meta:
        ordering = ['id']
    def __str__(self):
        return self.user.username

class Items(models.Model):
    cart = models.ForeignKey(Cartlist, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    order = models.BooleanField(default=False)
    created_at = models.DateField(auto_now_add=True)

    class Meta:
        ordering = ['id']

    def __str__(self):
        return '{}'.format(self.product)

Views.py

class AddCartView(generics.CreateAPIView):
    permission_classes = [IsAuthenticated]
    queryset =  Items.objects.all()
    serializer_class = AddCartSerializer

Serializer.py

class AddCartSerializer(serializers.ModelSerializer):
    class Meta:
        model = Items
        fields = ['product']

    def create(self, validated_data):
        user = self.context['request'].user 
        product = self.validated_data['product'] 
        if Cartlist.objects.filter(user=user):
            item = Items.objects.filter(cart__user=user,product=product)
            if item:
                item.quantity += 1
                item.save()
                return item
            else:
                item = Items.objects.create(cart=Cartlist.objects.get(user=user),**validated_data)
                item.save()
                return item
        
        else:
            cart = Cartlist.objects.create(user=user)
            cart.save()
            item = Items.objects.create(cart=cart,**validated_data)
            item.save()
            return item

问题原因

使用Items.objects.filter(cart__user=user, product=product)获取购物车商品时,filter()返回的是QuerySet对象(一个结果集合),而非单个Items实例,所以无法直接访问quantity属性。

修复方案
  1. 用exists()检查QuerySet是否存在数据,确认商品是否已在购物车中
  2. 若商品存在,通过first()或get()获取单个Items实例,再修改quantity字段
  3. 利用get_or_create简化购物车和商品的创建逻辑,减少冗余查询
修改后的Serializer代码
class AddCartSerializer(serializers.ModelSerializer):
    class Meta:
        model = Items
        fields = ['product']

    def create(self, validated_data):
        user = self.context['request'].user
        product = validated_data['product']
        
        # 自动获取或创建用户的购物车
        cart, _ = Cartlist.objects.get_or_create(user=user)
        
        # 检查购物车中是否已有该商品,不存在则创建
        item, created = Items.objects.get_or_create(
            cart=cart,
            product=product,
            defaults={'quantity': 1}
        )
        
        if not created:
            # 商品已存在,数量自增1
            item.quantity += 1
            item.save()
        
        return item
额外优化建议

如果担心并发场景下的数量更新错误(比如多个请求同时修改同一条记录),可以用Django的F()表达式实现原子更新,避免竞态条件:

from django.db.models import F

# 替换原有的item.quantity +=1和item.save()
Items.objects.filter(id=item.id).update(quantity=F('quantity') + 1)

内容的提问来源于stack exchange,提问作者Jerin Raju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:05:37