How to get all descendants of a node with Django mptt?

Question:

I would like my categories to show all items in that category including descendant categories, so the parent category contains all items for subcategories.

I have tried adding this method to my Category class in models.py

def get_all_products(self):
    # To display all items from all subcategories
    return Product.objects.filter(category__in=Category.objects.get_descendants(include_self=True))

And added this to my template.html, but it does’t work. What am I doing wrong?

    <li>{{ product.product_name }}</li>
{% empty %}
     <li>No items</li>
{% endfor %}
Asked By: rcomiskey

||

Answers:

I’ve realised where I was going wrong, the correct code is:

def get_all_products(self):
# To display all items from all subcategories
return Product.objects.filter(category__in=self.get_descendants(include_self=True))

{% for product in product.get_all_products %}
<li>{{ product.product_name }}</li>
{% empty %}
<li>No items</li>
{% endfor %}

Answered By: rcomiskey

In view function I use:

 products = models.Product.objects.filter(category__in=category.get_descendants(include_self=True))
Answered By: Serhii Zelenchuk

For example, you can get all descendants of a category with get_descendants() in views.py as shown below. *If include_self is True, the QuerySet will also include the model instance itself:

# "views.py"

from django.http import HttpResponse
from .models import Category, Product

def test(request):
    categories = Category.objects.get(name="Food").get_descendants()
    print(categories) 
    # <TreeQuerySet [<Category: Meat>, <Category: Fish>]>

    categories = Category.objects.get(name="Food").get_descendants(include_self=True)
    print(categories) 
    # <TreeQuerySet [<Category: Food>, <Category: Meat>, <Category: Fish>]>

    products = Product.objects.filter(category__in=categories)
    print(products)
    # <QuerySet [<Product: Beef>, <Product: Pork>, <Product: Salmon>

    return HttpResponse("Test")