Как отсортировать данные с предварительным упорядочиванием с помощью глубинной обработки из модели django в python?

У меня есть данные в базе данных, если преобразовать их в json, то данные будут выглядеть следующим образом:

[{
    'id': 27, 
    'has_sub_topic': 1, 
    'name': '123123', 
    'xml_name': '123123',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': None, 
    'subject_module_level_id': 25, 
    'order': 1
}, {
    'id': 34, 
    'has_sub_topic': 0, 
    'name': 'nosub', 
    'xml_name': 'nosub',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': None, 
    'subject_module_level_id': 25, 
    'order': 2
}, {
    'id': 31, 
    'has_sub_topic': 1, 
    'name': 'asdasda', 
    'xml_name': 'asdasda',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': None, 
    'subject_module_level_id': 25, 
    'order': 3
}, {
    'id': 28, 
    'has_sub_topic': 0, 
    'name': '11111', 
    'xml_name': '11111',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': 27, 
    'subject_module_level_id': 25, 
    'order': 1
}, {
    'id': 29, 
    'has_sub_topic': 0, 
    'name': '2222', 
    'xml_name': '2222',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': 27, 
    'subject_module_level_id': 25, 
    'order': 2
}, {
    'id': 32, 
    'has_sub_topic': 0, 
    'name': 'qweqwe', 
    'xml_name': 'qweqwe',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': 31, 
    'subject_module_level_id': 25, 
    'order': 1
}, {
    'id': 33, 
    'has_sub_topic': 0, 
    'name': 'zxczxcz', 
    'xml_name': 'zxczxcz',
    'validated': 1, 
    'created_at': '2021-12-02 02:19:44.962043', 
    'updated_at': '2021-12-02 02:19:44.962043', 
    'last_editor_id': 2,
    'parent_id': 31, 
    'subject_module_level_id': 25, 
    'order': 2
}]

Я получаю данные с помощью модели django с таким кодом:

topics = Topics.objects.order_by('order', 'parent')

Я хочу отсортировать данные с предварительным порядком обработки depth-first, так что это будет родитель первого порядка, под_топик с возрастающим порядком, и следующий родитель, и так далее. Таким образом, данные будут выглядеть так:

[
  {
    'id': 27,
    'has_sub_topic': 1,
    'name': '123123',
    'xml_name': '123123',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': None,
    'subject_module_level_id': 25,
    'order': 1
  },
  {
    'id': 28,
    'has_sub_topic': 0,
    'name': '11111',
    'xml_name': '11111',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': 27,
    'subject_module_level_id': 25,
    'order': 1
  },
  {
    'id': 29,
    'has_sub_topic': 0,
    'name': '2222',
    'xml_name': '2222',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': 27,
    'subject_module_level_id': 25,
    'order': 2
  },
  {
    'id': 34,
    'has_sub_topic': 0,
    'name': 'nosub',
    'xml_name': 'nosub',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': None,
    'subject_module_level_id': 25,
    'order': 2
  },
  {
    'id': 31,
    'has_sub_topic': 1,
    'name': 'asdasda',
    'xml_name': 'asdasda',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': None,
    'subject_module_level_id': 25,
    'order': 3
  },
  {
    'id': 32,
    'has_sub_topic': 0,
    'name': 'qweqwe',
    'xml_name': 'qweqwe',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': 31,
    'subject_module_level_id': 25,
    'order': 1
  },
  {
    'id': 33,
    'has_sub_topic': 0,
    'name': 'zxczxcz',
    'xml_name': 'zxczxcz',
    'validated': 1,
    'created_at': '2021-12-02 02:19:44.962043',
    'updated_at': '2021-12-02 02:19:44.962043',
    'last_editor_id': 2,
    'parent_id': 31,
    'subject_module_level_id': 25,
    'order': 2
  }
]

Я пробовал этот код, он работает с json данными, но он не работает, когда я получаю данные непосредственно с помощью модели django из базы данных.

topics_ordered = []
for topic in topics_test:
            if topic.has_sub_topic or not topic.parent_id:
                topics_ordered.append(topic)
                for topic_sub in topics_test:
                    if topic_sub.parent_id == topic.id:
                        topics_ordered.append(topic_sub)

Когда я получаю данные из базы данных напрямую с помощью модели django, она получает только родительские данные, вот так:

[
  {
    'id': 27,
    'has_sub_topic': True,
    'name': '123123',
    'xml_name': '123123',
    'parent_id': None,
    'order': 1
  },
  {
    'id': 34,
    'has_sub_topic': False,
    'name': 'nosub',
    'xml_name': 'nosub',
    'parent_id': None,
    'order': 2
  },
  {
    'id': 31,
    'has_sub_topic': True,
    'name': 'asdasda',
    'xml_name': 'asdasda',
    'parent_id': None,
    'order': 3
  }
]

Кто-нибудь знает, как решить эту проблему без преобразования данных в json?

Хорошо, я нашел решение, и оно очень простое. Вы можете просто использовать функцию sorted с лямбда-функцией, как это.

topics = sorted(topics, key=lambda d: d.parent.order if d.parent else d.order)

Вернуться на верх