如何编写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
相关产品推荐
相关产品推荐

