From 8b9e23098e2977994800e28e3220b4189d319df2 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Fri, 12 Sep 2025 12:26:16 -0700 Subject: [PATCH] save some fixes --- src/documents/models.py | 2 +- src/documents/serialisers.py | 16 ++++++++++++---- src/documents/tests/test_tag_hierarchy.py | 8 +++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/documents/models.py b/src/documents/models.py index 6b7bf84a7..7adfa4d19 100644 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -117,7 +117,7 @@ class Tag(MatchingModel, TreeNodeModel): verbose_name_plural = _("tags") def subtree_height(self, node: TreeNodeModel) -> int: - children = list(node.children) + children = list(node.get_children()) if not children: return 0 return 1 + max(self.subtree_height(child) for child in children) diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 14560c2c3..aebc63ea6 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -544,6 +544,14 @@ class TagSerializer(MatchingModelSerializer, OwnedObjectSerializer): def get_children(self, obj): return obj.get_children_pks() + # map to treenode's tn_parent + parent = serializers.PrimaryKeyRelatedField( + queryset=Tag.objects.all(), + allow_null=True, + required=False, + source="tn_parent", + ) + class Meta: model = Tag fields = ( @@ -579,13 +587,13 @@ class TagSerializer(MatchingModelSerializer, OwnedObjectSerializer): # Temporarily set parent on the instance if updating and use model clean() original_parent = self.instance.parent try: - self.instance.tn_parent = parent + self.instance.set_parent(parent) self.instance.clean() - except ValidationError as e: + except ValueError as e: logger.debug("Tag parent validation failed: %s", e) raise serializers.ValidationError({"parent": _("Invalid parent tag.")}) finally: - self.instance.tn_parent = original_parent + self.instance.set_parent(original_parent) else: # For new instances, create a transient Tag and validate temp = Tag(tn_parent=parent) @@ -1070,7 +1078,7 @@ class DocumentSerializer( tag_parents_being_removed = [ tag for tag in instance.tags.all() - if tag not in validated_data["tags"] and tag.children.count() > 0 + if tag not in validated_data["tags"] and tag.get_children_count() > 0 ] validated_data["tags"] = [ tag diff --git a/src/documents/tests/test_tag_hierarchy.py b/src/documents/tests/test_tag_hierarchy.py index 0be167f76..767e190cb 100644 --- a/src/documents/tests/test_tag_hierarchy.py +++ b/src/documents/tests/test_tag_hierarchy.py @@ -144,7 +144,7 @@ class TestTagHierarchy(APITestCase): format="json", ) assert resp.status_code == 400 - assert "parent" in resp.data + assert "Cannot set parent to a descendant" in str(resp.data["non_field_errors"]) def test_max_depth_on_create(self): a = Tag.objects.create(name="A1") @@ -182,7 +182,7 @@ class TestTagHierarchy(APITestCase): x = Tag.objects.create(name="X2") y = Tag.objects.create(name="Y2", tn_parent=x) - assert y.parent_id == x.id + assert y.parent_pk == x.pk # Moving X under D would make deepest node Y exceed depth 5 -> reject resp_fail = self.client.patch( @@ -191,7 +191,9 @@ class TestTagHierarchy(APITestCase): format="json", ) assert resp_fail.status_code == 400 - assert "parent" in resp_fail.data + assert "Maximum nesting depth exceeded" in str( + resp_fail.data["non_field_errors"], + ) # Moving X under C (depth 3) should be allowed (deepest becomes 5) resp_ok = self.client.patch(