Если вам нужно выполнить дополнительную обработку дерева, вы можете связать объекты Category друг с другом вместо косвенного обращения через родительский идентификатор.
Но в коде, который вы публикуетеосновная проблема заключается в повторяющихся вызовах, при которых вы должны сканировать весь список объектов:
parent = list(filter(filter_func, obj_list))
Если вы замените его словарем, ваша производительность будет намного лучше, так как время поиска для одного родителябудет ~ постоянное время
например, просто например
parent_map = dict([(c.id, c) for c in obj_list])
(очевидно, не делайте этого внутри метода get_top_parent_category (), так как это так же дорого)
Затем поиск родителя категории можно выполнить с помощью простого:
parent = parent_map[parent.id]
Тот же цикл, который вы имеете сейчас, будет на порядок быстрее.