Features: 1) Add dynamic tree prefetching for ordered and random scenarios; 2) Introduce create_ordered_tree_prefetch with depth-limiting capability;

Fixes: 1) Simplify ordering logic by consolidating expressions for both parent and child nodes;

Extra: 1) Refactor query construction for improved readability; 2) Remove redundant variable `parent_order` and `child_order`.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-09-15 13:54:05 +03:00
parent 7d2c85b03b
commit 143cd6804b

View file

@ -416,18 +416,49 @@ class CategoryFilter(FilterSet):
return queryset
if field == "?":
parent_order = "?"
child_order = "?"
order_expression = "?"
else:
parent_order = f"-{field}" if desc else field
child_order = parent_order
order_expression = f"-{field}" if desc else field
qs = queryset.order_by(parent_order).prefetch_related(None)
qs = queryset.order_by(order_expression).prefetch_related(None)
children_qs = (
Category.objects.all().order_by(child_order) if child_order != "?" else Category.objects.all().order_by("?")
)
return qs.prefetch_related(Prefetch("children", queryset=children_qs))
def create_ordered_tree_prefetch(max_depth=10):
if field == "?":
def build_random_prefetch(depth):
if depth <= 0:
return None
children_qs = Category.objects.all().order_by("?")
nested_prefetch = build_random_prefetch(depth - 1)
if nested_prefetch:
children_qs = children_qs.prefetch_related(nested_prefetch)
return Prefetch("children", queryset=children_qs)
return build_random_prefetch(max_depth)
else:
def build_ordered_prefetch(depth):
if depth <= 0:
return None
children_qs = Category.objects.all().order_by(order_expression, "tree_id", "lft")
nested_prefetch = build_ordered_prefetch(depth - 1)
if nested_prefetch:
children_qs = children_qs.prefetch_related(nested_prefetch)
return Prefetch("children", queryset=children_qs)
return build_ordered_prefetch(max_depth)
tree_prefetch = create_ordered_tree_prefetch()
if tree_prefetch:
qs = qs.prefetch_related(tree_prefetch)
return qs
def filter_name(self, queryset, _name, value):
search_results = process_query(query=value, request=self.request)["categories"]