В дереве фильтра узлы и его дочерние элементы

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

Все категории активны, дерево выглядит так:

Category 1-1
    Product 1-1
    Category 2-1
        Product 2-1
        Category 3-1
            Product 3-1
        Category 3-2
    Category 2-2
        Product 2-2

Если я установлю Category 2-1 в inactiveЯ хочу увидеть результат, как это:

Category 1-1
    Product 1-1
    Category 2-2
        Product 2-2

Я создал метод, который делает фильтр, но я использую рекурсию, если дерево, например, имеет очень высокую глубину depth=100 и категория неактивна в depth = 2Я получаю максимальную ошибку рекурсии глубины.

def filter_category_products(self):
    inactive_category_ids = get_inactive_categories_ids()
    queryset = Category.objects.exclude(id__in=inactive_category_ids).prefetch_related(Prefetch('product_set', queryset=Product.objects.filter(is_active=True)))

    return queryset

def get_inactive_categories_ids():
    inactive_categories_ids_query = Category.objects.filter(is_active=False).values_list('id', flat=True)

    inactive_ids = []
    for i in inactive_categories_ids_query:
        inactive_ids.append(i)

    ids = []

    while inactive_ids:
        for inactive_id in inactive_ids:
            if(inactive_id not in ids):
                ids.append(inactive_id)
        inactive_ids = Category.objects.filter(parent_id__in = inactive_ids).values_list('id', flat=True)

    return ids

Модели:

class Category(MPTTModel):
    name = models.CharField(max_length=50, blank=False, unique=True)
    is_active = models.BooleanField(default=True)
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children', db_index=True)

    tree_objects=CategoryQueryManager()


class Product(models.Model):
    name = models.CharField(max_length=50, blank=False, unique=True)
    price = models.DecimalField(blank=False, null=False, decimal_places=2, max_digits=4)
    is_active = models.BooleanField(default=True)
    category = TreeForeignKey('Category', on_delete=models.CASCADE, null=True, blank=True, db_index=True)

Мой вопрос был бы, есть ли другой алгоритм, как я мог бы фильтровать это без рекурсии, чтобы я мог избежать ошибки и редактирования максимального предела рекурсии в Python sys ресурс.

0 ответов

Другие вопросы по тегам