В дереве фильтра узлы и его дочерние элементы
У меня есть приложение с категориями и товарами, категории и товары могут быть неактивными, по неактивной категории не показывать своих детей, например:
Все категории активны, дерево выглядит так:
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
ресурс.