如何编写Django模型查询以获取产品列表,包含是否在愿望清单中?
models.py
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)
我想要获取所有的产品,就像使用 product.objects.all() 这样,同时检查特定的产品是否在购物车和愿望清单中。
2 个回答
0
你可以使用一个叫做 Exists
表达式 [Django-doc] 来做一些操作:
from django.db.models import OuterRef, Exists
Product.objects.annotate(
in_wishlist=Exists(
wishlist.objects.filter(
product_id=OuterRef('pk'), user_id_id=request.user.id
)
)
)
从这个查询结果中得到的 Product
对象会多一个属性 .in_wishlist
,如果有一个 wishlist
对象的 user_id_id
是当前用户的 ID,并且 product_id
是对应的产品,那么这个属性的值就是 True
。
注意:通常情况下,
ForeignKey
字段后面不需要加…_id
后缀,因为 Django 会自动添加一个带有…_id
后缀的“兄弟”字段。所以应该用user
,而不是。user_id
注意:通常建议使用
settings.AUTH_USER_MODEL
[Django-doc] 来引用用户模型,而不是直接使用User
模型 [Django-doc]。想了解更多信息,可以查看文档中关于 引用User
模型 的部分。
注意:在 Django 中,模型名称使用 PascalCase 格式,而不是 snake_case 格式,所以你可能想把模型的名字从
改成wishlist
WishList
。
0
你的模型设置有问题。
一个愿望清单只能分配给一个用户,这样使用ForeignKey
是对的。
但是,根据你上面的代码,你把一个愿望清单只分配给了一个产品。因为你使用了ForeignKey
(和用户的关系是一样的),所以你的愿望清单不能包含多个产品。
相反,你应该使用多对多关系。因为一个愿望清单可以包含多个产品,而一个产品也可以被多个愿望清单包含。
class wishlist(models.Model):
products = models.ManyToManyField(Product)
user_id = models.ForeignKey(Account, on_delete=models.CASCADE)
create_at = models.DateTimeField(auto_now_add=True)
from django.db.models import Prefetch
# Prefetch related products in cart and wishlist for the user
cart_prefetch = Prefetch('cart_set', queryset=Cart.objects.filter(user=user), to_attr='user_cart')
wishlist_prefetch = Prefetch('wishlist_set', queryset=Wishlist.objects.filter(user=user), to_attr='user_wishlist')
products = Product.objects.prefetch_related(cart_prefetch, wishlist_prefetch).all()
# Iterate over products
for product in products:
in_cart = any(cart for cart in getattr(product, 'user_cart', []))
in_wishlist = any(wishlist for wishlist in getattr(product, 'user_wishlist', []))
print(f"Product {product.name} is in cart: {in_cart}, is in wishlist: {in_wishlist}")