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

如何编写Django模型查询获取商品列表并判断是否在购物车或心愿单

如何查询所有商品并判断是否在购物车/心愿单中?

需求:获取所有商品(等价于Product.objects.all()),同时判断每个商品是否存在于当前用户的购物车或心愿单中。

现有模型定义

# models.py
class Product(models.Model):
    code = models.CharField(max_length=50, default=None, null=True, blank=True, unique=True)
    name = models.CharField(max_length=100)
    category_id = models.ForeignKey(category, on_delete=models.CASCADE)   
    size_id = models.ForeignKey(size, on_delete=models.CASCADE)
    cost = models.IntegerField()
    tax_id = models.ForeignKey(Tax, on_delete=models.CASCADE)
    price = models.IntegerField()

class wishlist(models.Model):
    product_id = models.ForeignKey(Product,  on_delete=models.CASCADE, 
                                      error_messages = {'unique': 'This Product is already in exist',})
    user_id = models.ForeignKey(Account, on_delete=models.CASCADE)
    create_at = models.DateTimeField(auto_now_add=True)

解决方案:使用Exists子查询标注状态

Django的Exists数据库函数可以高效为每个商品添加布尔字段,标记是否存在于用户的心愿单/购物车中,避免N+1查询问题。

1. 查询所有商品并标注是否在心愿单

from django.db.models import Exists, OuterRef

# 假设当前用户通过request.user获取
products = Product.objects.annotate(
    is_in_wishlist=Exists(
        wishlist.objects.filter(
            product_id=OuterRef('pk'),  # 关联当前商品主键
            user_id=request.user        # 指定当前用户
        )
    )
).all()

2. 同时标注购物车状态(假设购物车模型为Cart)

如果需要同时判断购物车,只需在annotate中添加另一个Exists子查询:

products = Product.objects.annotate(
    is_in_wishlist=Exists(
        wishlist.objects.filter(
            product_id=OuterRef('pk'),
            user_id=request.user
        )
    ),
    is_in_cart=Exists(
        Cart.objects.filter(
            product_id=OuterRef('pk'),
            user_id=request.user
        )
    )
).all()

使用方式

遍历查询结果时,直接通过商品对象的属性判断状态:

for product in products:
    if product.is_in_wishlist:
        print(f"{product.name} 在心愿单中")
    if product.is_in_cart:
        print(f"{product.name} 在购物车中")

额外建议

  • Django模型类名建议首字母大写(如Wishlist而非wishlist),符合PEP8规范;
  • 外键字段名建议去掉_id后缀(如product而非product_id),Django会自动生成product_id作为数据库字段名,代码可读性更好。

内容的提问来源于stack exchange,提问作者shyam rathod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:48:39