在类别页面中呈现与一个类别的子类别之一相关的所有产品

Render all products that relate to one of subcategories of one category, in category page

我有一个问题。我正在 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):
        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时,就会出错