fix: prevent cycles and hierarchy breaks in node add-children API

This commit is contained in:
Bai
2026-05-09 16:21:13 +08:00
parent a48bdd0212
commit 3613f9d7af
2 changed files with 11 additions and 0 deletions

View File

@@ -94,6 +94,10 @@ class NodeAddChildrenApi(generics.UpdateAPIView):
node_ids = request.data.get("nodes")
children = Node.objects.filter(id__in=node_ids)
for node in children:
if node.is_ancestor(instance):
# 如果 node 是 instance 的祖先节点,则不能添加为 instance 的子节点,否则会形成环,出现断层
error = _("Node {} is an ancestor of node {}, can't be added as its child".format(node.value, instance.value))
return Response(data={'error': error}, status=status.HTTP_400_BAD_REQUEST)
node.parent = instance
update_nodes_assets_amount.delay(ttl=5, node_ids=(instance.id,))
return Response("OK")

View File

@@ -94,6 +94,10 @@ class FamilyMixin:
def is_children(self, other):
children_pattern = other.get_children_key_pattern(with_self=False)
return re.match(children_pattern, self.key)
def is_descendant(self, other):
all_children_pattern = other.get_all_children_pattern(with_self=False)
return re.match(all_children_pattern, self.key)
def get_children(self, with_self=False):
q = Q(parent_key=self.key)
@@ -204,6 +208,9 @@ class FamilyMixin:
def is_parent(self, other):
return other.is_children(self)
def is_ancestor(self, other):
return other.is_descendant(self)
@property
def parent(self):
if self.is_org_root():