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

I had a question. I am creating an ecommerce website in django. There, I have categories and subcategories. When I enter to subcategory page, I able to render all products that relate to this subcategory. But, when I wanted to render all product that relate on one parent category, I am having troubles. So, I have some subcategories in one category. In that category page, I want to render all products that relate to one of subcategories of this category. Can you help me please? 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)

Here I want to save all products that relate the category in products_all. Looking forward to your help!



Solution 1:[1]

You can do it using Q function:

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))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LaCharcaSoftware