Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I query objects of all children of a node with Django mptt?

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]
like image 712
Rivadiz Avatar asked Oct 26 '15 21:10

Rivadiz


2 Answers

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))
like image 145
Tebe Tensing Avatar answered Oct 12 '22 17:10

Tebe Tensing


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

like image 45
abrunet Avatar answered Oct 12 '22 15:10

abrunet