def get_ordered_insertion_target(self, node, parent):
"""
Attempts to retrieve a suitable right sibling for ``node``
underneath ``parent`` (which may be ``None`` in the case of root
nodes) so that ordering by the fields specified by the node's class'
``order_insertion_by`` option is maintained.
Returns ``None`` if no suitable sibling can be found.
"""
right_sibling = None
# Optimisation - if the parent doesn't have descendants,
# the node will always be its last child.
if parent is None or parent.get_descendant_count() > 0:
opts = node._mptt_meta
order_by = opts.order_insertion_by[:]
filters = self.insertion_target_filters(node, order_by)
if parent:
filters = filters & Q(**{opts.parent_attr: parent})
# Fall back on tree ordering if multiple child nodes have
# the same values.
order_by.append(opts.left_attr)
else:
filters = filters & Q(**{opts.parent_attr: None})
# Fall back on tree id ordering if multiple root nodes have
# the same values.
order_by.append(opts.tree_id_attr)
queryset = node.__class__._tree_manager.db_manager(node._state.db).filter(filters).order_by(*order_by)
if node.pk:
queryset = queryset.exclude(pk=node.pk)
try:
right_sibling = queryset[:1][0]
except IndexError:
# No suitable right sibling could be found
pass
return right_sibling
评论列表
文章目录