Skip to content

Is it feasible to support get queryset descendants or ancestors like features in django-mptt #28

@jukanntenn

Description

@jukanntenn

django-mptt has a feature get_queryset_descendants which query the descendants of tree nodes represented by a queryset. However, TreeQuerySet.descendants method in django-tree-queries only support query descendants of a certain tree node. After doing some experiments, I find a way to implement such feature, like bellow:

def descendants(self, of, include_self=False):
    ...
    extra_where = " or ".join(['instr(__tree.tree_path, "{sep}{pk}{sep}") <> 0'.format(
                        pk=self.model._meta.pk.get_db_prep_value(pk(obj), connection),
                        sep=SEPARATOR,
                    ) for obj in of])
            queryset = self.with_tree_fields().extra(
                # NOTE! The representation of tree_path is NOT part of the API.
                where=[
                    # XXX This *may* be unsafe with some primary key field types.
                    # It is certainly safe with integers.
                    extra_where
                ]
            )

The idea is if of parameter is a queryset rather than a single model instance, changing the where clause to or.

The downside of this approach is we need an extra database query. I also have no idea if there is performance issue for a large queryset.

Another idea I come up with is inject a a subquery in CTE, like bellow:
change:

SELECT
            0 AS tree_depth,
            array[T.{pk}] AS tree_path,
            array[{order_by}] AS tree_ordering,
            T."{pk}"
        FROM {db_table} T
        WHERE T."{parent}" IS NULL

to:

SELECT
            0 AS tree_depth,
            array[T.{pk}] AS tree_path,
            array[{order_by}] AS tree_ordering,
            T."{pk}"
        FROM {db_table} T
        WHERE T."{parent}" in <<pks of queryset>>

but I also have no idea that this is feasible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions