简体   繁体   中英

Get parent by its children in Django Queryset

I have this model:

Department(models.Model):
    title =  models.CharField(max_length=128)
    reference = models.ForeignKey('self', related_name='reference')

As you see, each object of this model can have parent and conversely.

For example, these are department's objects:

id = 1 , title = 'dep 1' , reference_id = Null
id = 2 , title = 'dep 2' , reference_id = 1
id = 3 , title = 'dep 3' , reference_id = Null
id = 4 , title = 'dep 4' , reference_id = 1
id = 5 , title = 'dep 5' , reference_id = 3
id = 6 , tiltl = 'dep 6' , reference_id = 3
id = 7 , title = 'dep 7' , reference_id = 3
id = 8 , title = 'dep 8' , reference_id = 9
id = 9 , title = 'dep 9' , reference_id = Null
id = 10, title = 'dep 10', reference_id = 9

Now I want to get list of objects that has this condition: Each parent by its children . like this:

- dep 1 
    dep 2 
    dep 4 
- dep 3 
    dep 5
    dep 6
    dep 7
- dep 9
    dep 8 
    dep 10

How can I do that? (Can I create this list just with Django ORM ?)

Update This is my department levels:

Department_Level = (
    (1, 'headquarters'),
    (2, 'unit'),
    (3, 'center'),
)
level = models.IntegerField(choices=Department_Level,default=.Department_Level[2][0])    

And I want just level 2 and 3 in my list.

It may be works using ArrayAgg . Please try it.

from django.contrib.postgres.aggregates import ArrayAgg


# dept_id is root department id
dept_list = Department.objects.filter(id=dept_id).annotate(reference_list=ArrayAgg('department__reference'))

First, get all objects

mapper = dict(Department.objects.values_list("id", "reference_id"))

This will result in a dict (child to parent)

{1: None, 2: 1, ...}

Convert it dict with parent to children

res = dict()
for child, parent in mapper.items():
     res.setdefault(parent, []).append(child)

Now you can construct a data structure over it however you like. You can also get the grandchildren by finding the children of all children of an item.

Best to construct a tree structure and write a class method which returns the tree with res as input

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM