Отображение всех продуктов, относящихся к одной из подкатегорий одной категории, на странице категории
У меня возник вопрос. Я создаю сайт электронной коммерции на django. Там у меня есть категории и подкатегории. Когда я захожу на страницу подкатегории, я могу отобразить все продукты, которые относятся к этой подкатегории. Но когда я хочу отобразить все товары, относящиеся к одной родительской категории, у меня возникают проблемы. Итак, у меня есть несколько подкатегорий в одной категории. На странице этой категории я хочу отобразить все продукты, которые относятся к одной из подкатегорий этой категории. Не могли бы вы мне помочь? models.py
class Category(models.Model):
parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255)
image = models.ImageField(null=True, blank=True, verbose_name="Изображение")
ordering = models.IntegerField(default=0)
is_featured = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Categories'
ordering = ('ordering',)
def __str__(self):
if self.parent is not None:
return f"{self.parent}/{self.title}"
return self.title
@property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
def get_absolute_url(self):
return '/%s/' % (self.slug)
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
parent = models.ForeignKey('self', related_name='variants', on_delete=models.CASCADE, blank=True, null=True)
name = models.CharField(max_length=200, verbose_name="Название продукта")
price = models.IntegerField(verbose_name="Цена")
slug = models.SlugField(max_length=255)
description = models.CharField(max_length=5000,blank=True, verbose_name="Описание:")
image = models.ImageField(null=True, blank=True, verbose_name="Изображение")
novinki = models.BooleanField(default=False, verbose_name="Новинки")
popularnye = models.BooleanField(default=False, verbose_name="Популарные")
def __str__(self):
return self.name
class Meta:
verbose_name = 'Продукты'
verbose_name_plural = "Продукты"
@property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
views.py
def category_detail(request, slug):
data = cartData(request)
cartItems = data['cartItems']
order = data['order']
items = data['items']
categories_for_menu = Category.objects.filter(parent=None)[:3]
categories = Category.objects.filter(parent=None)
category = get_object_or_404(Category, slug=slug)
**products_all = Product.objects.filter(category.parent==category)**
print(products_all)
products = category.products.all()
context = {'items' : items, 'order' : order, 'cartItems' : cartItems, 'products':products, 'category':category, 'categories':categories,'categories_for_menu':categories_for_menu,'products_all':products_all}
return render(request, "store/categories.html", context)
Здесь я хочу сохранить все продукты, которые относятся к категории в products_all. Надеюсь на вашу помощь!
Вы можете сделать это с помощью функции Q:
from django.db.models import Q
category = get_object_or_404(Category, slug=slug)
products = Product.objects.filter(Q(category = category)|Q(category__parent = category))
class Category(models.Model):
# ...
root = models.ForeignKey('self', on_delete=models.CASCADE)
# ...
def save(self, *args, **kwargs): # Use pre_save signal is better
self.root = self.parent.root if self.parent else self
# I didn't debug it. Maybe it has some bug.
super(Category, self).save(*args, **kwargs)
# query
Product.objects.filter(category__root=(...))
Я не согласен с этим ответом:
products = Product.objects.filter(Q(category = category)|Q(category__parent = category))
Когда ваша категория имеет глубину более 2, она будет неправильной.