13

I am trying to get the objects of all the children of a given node on Django with django-mppt

I have a model designed as shown below, the classes/categories (node) with the same indent level defines siblings, inner indents are children. The objects tagged with a category are shown just below the category (node). The objects start with a - symbol. The numbers along the classes/categories (nodes) are the ids.

all the nodes are the instances of Category class with the id given.

high school (1)
    class 8 (2)
        division a (3)
            -Billie
            -Tre
            -Mike

        division b (4)
            -Patrik
            -Pete
            -Andy
    class 9 (3)
        division a (8)
            -Mark
            -Tom
            -Travis

        division b (5)
            -Gerard
            -Frank
            -Mikey

    class 10  (4)
        division a (6)
            -Hayley
            -Jeremy
            -Taylor

        division b (7)
            -Steven
            -Slash
            -Izzy

I can get the query sets of a specific node this way,

>>> Category.objects.get(pk=7).product_set.all()
[Steven, Slash, Izzy]


>>> Category.objects.get(pk=4).product_set.all()
[Mark, Tom, Travis]

How do I query with pk=1, pk=2, pk=3 or pk=4 to get all the child objects?

example,

the query for pk=2 query must return

[Billie, Tre, Mike, Patrik, Pete, Andy]

3 Answers3

30
Category.objects.get(pk=2).get_descendants(include_self=True)

This will get you all category descendants including self.

Assuming that your Product model has a Foreign key category, you can use:

Product.objects.filter(category__in=Category.objects.get(pk=2)\
    .get_descendants(include_self=True))
Tebe Tensing
  • 1,286
  • 9
  • 10
  • Descendants from what field though? How does Category only know to fetch descendants from Product? What if Category also has descendants from Widget? Does it fetch from both of these, or do you have to specify which one to fetch from? – kloddant Feb 23 '17 at 15:53
  • Where does this get_descendants came from? – Chetan Vashisth May 27 '21 at 11:46
4

Category.objects.get(pk=1).get_leafnodes() is what you're looking for.

(django-mptt docs)

Fush
  • 2,469
  • 21
  • 19
3

Django mptt provides two methods to retrieve children.

From the docs

MPTTModel.get_children(*args, **kwargs)

Returns a QuerySet containing the immediate children of this model >instance, in tree order.

The benefit of using this method over the reverse relation provided by the ORM to the instance’s children is that a database query can be avoided in the case where the instance is a leaf node (it has no children).

If called from a template where the tree has been walked by the cache_tree_children filter, no database query is required.

And

MPTTModel.get_leafnodes(*args, **kwargs)

Creates a QuerySet containing leafnodes of this model instance, in tree order.

If include_self is True, the QuerySet will also include this model instance (if it is a leaf node)

I'm not sure how your models are set up but I'm not sure why you use mptt here. You are using Category/Product but it seems to be student or people and work groups.

Maybe you can define EstablishmentLevel, Level|, StudentGroup, Student models and instead of using mptt function query something like:

Student.objects.filter(studentgroup__level__pk=1)

See the Django doc

Hope that helped

Community
  • 1
  • 1
abrunet
  • 1,122
  • 17
  • 31