эффективная функция для получения набора запросов предков набора запросов mptt

Есть ли у кого-нибудь эффективный алгоритм для получения всех предков набора запросов mptt? Лучшее, что я мог подумать of пока выглядит примерно так:

def qs_ancestors(queryset):
    if isinstance(queryset, EmptyQuerySet):
        return queryset
    queryset_aggs = queryset.values_list('tree_id', 'level').annotate(max_lft=Max('lft'), min_rght=Min('rght'))
    new_queryset = queryset.none()
    for tree_id, level, max_lft, min_rght in queryset_aggs:
        ancestors = MyModel.objects.filter(
           tree_id=tree_id,
           level__lt=level, 
           lft__lte=max_lft,
           rght__gte=min_rght,
        )
        new_queryset = ancestors | new_queryset
    return new_queryset

У этого подхода есть две проблемы:

  1. Он не работает, если есть ветки, которые не находятся рядом друг с другом (т.е. на самом деле это не работает)
  2. Это крайне неэффективен, потому что в конечном запросе есть предложения number_of_trees * number_of_levels , которые могут очень быстро стать очень большими

. Я готов кэшировать предков где-нибудь еще, но я не могу придумать способ сделать это Я подумывал добавить поле со списком идентификаторов предков, разделенных запятыми, а затем выполнить GROUP_CONCAT (я в MySQL) внутри дополнительной функции, но я думаю, что это может стать огромным / медленным.

15
задан Bacon 24 June 2011 в 19:58
поделиться