Как написать запрос к модели Django, чтобы получить список продуктов с товарами, доступными в wishlist или нет?
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(), с проверкой конкретного продукта, доступного в корзине и списке желаний или нет
Неправильная настройка моделей.
Один список желаний может быть назначен одному владельцу (пользователю). Да правильное использование 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}")
Вы можете использовать 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
, который будет True
, если существует объект wishlist
с request.user.id
как user_id_id
, и product_id
для этого продукта.
Примечание: Обычно не добавляют суффикс
…_id
к полюForeignKey
, так как Django автоматически добавит поле-"близнец" с суффиксом…_id
. Поэтому он должен бытьuser
, вместо.user_id
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Примечание: Модели в Django пишутся на PascalCase, а не snake_case, поэтому вы можете переименовать модель из
вWishlist
wishlist
.