def _get_queryset_relatives(self, queryset, direction, include_self):
        assert self.model is queryset.model

        opts = queryset.model._mptt_meta

        filters = Q()

        e = 'e' if include_self else ''
        max_op = 'lt' + e
        min_op = 'gt' + e
        if direction == 'asc':
            max_attr = opts.left_attr
            min_attr = opts.right_attr
        elif direction == 'desc':
            max_attr = opts.right_attr
            min_attr = opts.left_attr

        tree_key = opts.tree_id_attr
        min_key = '%s__%s' % (min_attr, min_op)
        max_key = '%s__%s' % (max_attr, max_op)

        q = queryset.order_by(opts.tree_id_attr, opts.parent_attr, opts.left_attr).only(
            opts.tree_id_attr,
            opts.left_attr,
            opts.right_attr,
            min_attr,
            max_attr,
            opts.parent_attr,
            # These fields are used by MPTTModel.update_mptt_cached_fields()
            *opts.order_insertion_by
        )

        if not q:
            return self.none()

        for group in groupby(
                q,
                key=lambda n: (
                    getattr(n, opts.tree_id_attr),
                    getattr(n, opts.parent_attr + '_id'),
                )):
            next_lft = None
            for node in list(group[1]):
                tree, lft, rght, min_val, max_val = (getattr(node, opts.tree_id_attr),
                                                     getattr(node, opts.left_attr),
                                                     getattr(node, opts.right_attr),
                                                     getattr(node, min_attr),
                                                     getattr(node, max_attr))
                if next_lft is None:
                    next_lft = rght + 1
                    min_max = {'min': min_val, 'max': max_val}
                elif lft == next_lft:
                    if min_val < min_max['min']:
                        min_max['min'] = min_val
                    if max_val > min_max['max']:
                        min_max['max'] = max_val
                    next_lft = rght + 1
                elif lft != next_lft:
                    filters |= Q(**{
                        tree_key: tree,
                        min_key: min_max['min'],
                        max_key: min_max['max'],
                    })
                    min_max = {'min': min_val, 'max': max_val}
                    next_lft = rght + 1
            filters |= Q(**{
                tree_key: tree,
                min_key: min_max['min'],
                max_key: min_max['max'],
            })

        return self.filter(filters)
Get images for expressions
dataset/ETHPy150Open django-mptt/django-mptt/mptt/managers.py/TreeManager._get_queryset_relatives--crossover with--dataset/ETHPy150Open cortical-io/python-client-sdk/cortical/imageApi.py/ImageApi.getImageForExpression