I have a model named Topics with data like this:
id | has_sub_topic | parent_id | subject_module_level_id | order |
---|---|---|---|---|
27 | 1 | NULL | 25 | 1 |
31 | 1 | NULL | 25 | 2 |
34 | 0 | NULL | 25 | 3 |
28 | 0 | 27 | 25 | 1 |
29 | 0 | 27 | 25 | 2 |
40 | 1 | 27 | 25 | 3 |
32 | 0 | 31 | 25 | 1 |
33 | 0 | 31 | 25 | 2 |
41 | 1 | 40 | 25 | 1 |
43 | 0 | 40 | 25 | 2 |
44 | 1 | 40 | 25 | 3 |
42 | 0 | 41 | 25 | 1 |
45 | 0 | 44 | 25 | 1 |
47 | 1 | 44 | 25 | 2 |
48 | 0 | 47 | 25 | 1 |
I Want to sort it by the parent first and then proceed to its children like depth-first processing and get the data only the topics that no has_sub_topic. So, the data will be sorted by order like this: https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif and get the data only 4, 7, 8, 10
Previously I try using sorted function, but it didn't go well with many child. So, I must use recursive function. My code using recursive is like this:
# Example data for topics
import pandas as pd
topics = pd.DataFrame({
'id': [27, 31, 34, 28, 29, 40, 32, 33, 41, 43, 44, 42, 45, 47, 48],
'has_sub_topic': [1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0],
'parent_id': [None, None, None, 27, 27, 27, 31, 31, 40, 40, 40, 41, 44, 44, 47],
'subject_module_level_id': [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25],
'order': [1, 2, 3, 1, 2, 3, 1, 2, 1, 2, 3, 1, 1, 2, 1]
})
def topic_child_order(topic, list_topics=None):
if list_topics is None: list_topics = []
if topic.has_sub_topic:
topics = Topics.objects.filter(parent=topic).order_by('order')
for child in topics:
result = topic_child_order(child, list_topics)
else:
result = topic
list_topics.append(result)
return list_topics
topics = Topics.objects.filter(
subject_module_level_id=25,
parent=None
).order_by('order')
topics_order = []
for topic in topics:
topics_order.append(topic_child_order(topic))
The result is like this:
[
[
<Topics: Topicsobject(28)>,
<Topics: Topicsobject(29)>,
<Topics: Topicsobject(42)>,
[
...
],
<Topics: Topicsobject(43)>,
<Topics: Topicsobject(45)>,
<Topics: Topicsobject(48)>,
[
...
],
[
...
],
[
...
],
[
...
]
],
[
<Topics: Topicsobject(32)>,
<Topics: Topicsobject(33)>,
[
...
]
],
[
<Topics: Topicsobject(34)>
]
]
The sort order is right but I don't know why the result has empty lists. Anyone know how to fix this? Or anyone know how to do this more better way so the result only return in one list not nested list?