Как эффективно установить данные порядка для родительского объекта и его дочерних объектов с помощью рекурсии, используя python?
Я использовал django для модели с именем Topics и данными таблицы в базе данных mysql со значением заказа по умолчанию 1 следующим образом:
id | has_sub_topic | parent_id | subject_module_level | порядок |
---|---|---|---|---|
1 | 0 | NULL | 1 | 1 |
2 | 0 | NULL | 2 | 1 |
3 | 0 | NULL | 3 | 1 |
27 | 1 | NULL | 25 | 1 |
28 | 0 | 27 | 25 | 1 |
29 | 0 | 27 | 25 | 1 |
31 | 1 | NULL | 25 | 1 |
32 | 0 | 31 | 25 | 1 |
33 | 0 | 31 | 25 | 1 |
34 | 0 | NULL | 25 | 1 |
40 | 1 | 27 | 25 | 1 |
41 | 1 | 40 | 25 | 1 |
42 | 0 | 41 | 25 | 1 |
43 | 0 | 40 | 25 | 1 |
44 | 1 | 40 | 25 | 1 |
45 | 0 | 44 | 25 | 1 |
47 | 1 | 44 | 25 | 1 |
48 | 0 | 47 | 25 | 1 |
Я хочу установить данные заказа на основе его subject_module и его родителя. Таким образом, данные в таблице будут выглядеть следующим образом:
id | has_sub_topic | parent_id | subject_module_level | порядок |
---|---|---|---|---|
1 | 0 | NULL | 1 | 1 |
2 | 0 | NULL | 2 | 1 |
3 | 0 | NULL | 3 | 1 |
27 | 1 | NULL | 25 | 1 |
28 | 0 | 27 | 25 | 1 |
29 | 0 | 27 | 25 | 2 |
31 | 1 | NULL | 25 | 2 |
32 | 0 | 31 | 25 | 1 |
33 | 0 | 31 | 25 | 2 |
34 | 0 | NULL | 25 | 3 |
40 | 1 | 27 | 25 | 3 |
41 | 1 | 40 | 25 | 1 |
42 | 0 | 41 | 25 | 1 |
43 | 0 | 40 | 25 | 2 |
44 | 1 | 40 | 25 | 3 |
45 | 0 | 44 | 25 | 1 |
47 | 1 | 44 | 25 | 2 |
48 | 0 | 47 | 25 | 1 |
Вот пример данных в pandas:
# Example data for topics
import pandas as pd
topics = pd.DataFrame({
'id': [1, 2, 3, 27, 28, 29, 31, 32, 33, 34, 40, 41, 42, 43, 44, 45, 47, 48],
'has_sub_topic': [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0],
'parent_id': [None, None, None, None, 27, 27, None, 31, 31, None, 27, 40, 41, 40, 40, 44, 44, 47],
'subject_module_level_id': [1, 2, 3, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25],
'order': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
})
Я правильно установил порядок с помощью этого кода:
topics = Topics.objects.all().order_by('order')
for topic in topics:
re_order_topics(topic)
def re_order_topics(topic):
sibling_order = 1
child_order = 1
siblings = Topics.objects.filter(
parent=topic.parent,
subject_module_level=topic.subject_module_level
).order_by('order')
if topic.has_sub_topic:
childs = Topics.objects.filter(parent=topic).order_by('order')
for child in childs:
child.order = child_order
child_order += 1
child.save()
re_order_topics(child)
if len(siblings) > 1:
for sibling in siblings:
sibling.order = sibling_order
sibling_order += 1
sibling.save()
else:
topic.order = 1
topic.save()
Но, как вы можете видеть, мой код очень неэффективен, потому что он устанавливает порядок для темы, которая была переупорядочена более одного раза рекурсивным и первым for-циклом. Если в базе данных будет гораздо больше данных, то время выполнения будет очень долгим из-за этого. Кто-нибудь знает, как это можно эффективно сделать?