| 123456789101112131415161718192021222324252627282930313233343536 |
- from utilities.querysets import RestrictedQuerySet
- class PrefixQuerySet(RestrictedQuerySet):
- def annotate_depth(self, limit=None):
- """
- Iterate through a QuerySet of Prefixes and annotate the hierarchical level of each. While it would be preferable
- to do this using .annotate() on the QuerySet to count the unique parents of each prefix, that approach introduces
- performance issues at scale.
- Because we're adding a non-field attribute to the model, annotation must be made *after* any QuerySet
- modifications.
- """
- queryset = self
- stack = []
- for p in queryset:
- try:
- prev_p = stack[-1]
- except IndexError:
- prev_p = None
- if prev_p is not None:
- while (p.prefix not in prev_p.prefix) or p.prefix == prev_p.prefix:
- stack.pop()
- try:
- prev_p = stack[-1]
- except IndexError:
- prev_p = None
- break
- if prev_p is not None:
- prev_p.has_children = True
- stack.append(p)
- p.depth = len(stack) - 1
- if limit is None:
- return queryset
- return list(filter(lambda p: p.depth <= limit, queryset))
|