浏览代码

feat: remove subtree (#17647) (#17954)

* feat: remove subtree

* test: remove_subtree

(cherry picked from commit d05ed27a01)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
version-14
mergify[bot] 2 年前
committed by GitHub
父节点
当前提交
5f4e0531cd
找不到此签名对应的密钥 GPG 密钥 ID: 4AEE18F83AFDEB23
共有 2 个文件被更改,包括 27 次插入0 次删除
  1. +5
    -0
      frappe/tests/test_nestedset.py
  2. +22
    -0
      frappe/utils/nestedset.py

+ 5
- 0
frappe/tests/test_nestedset.py 查看文件

@@ -12,6 +12,7 @@ from frappe.utils.nestedset import (
NestedSetRecursionError,
get_descendants_of,
rebuild_tree,
remove_subtree,
)

records = [
@@ -206,6 +207,10 @@ class TestNestedSet(FrappeTestCase):
with self.assertRaises(NestedSetChildExistsError):
frappe.delete_doc("Test Tree DocType", "Parent 1")

def test_remove_subtree(self):
remove_subtree("Test Tree DocType", "Parent 2")
self.test_basic_tree()

def test_merge_groups(self):
global records
el = {"some_fieldname": "Parent 2", "parent_test_tree_doctype": "Root Node", "is_group": 1}


+ 22
- 0
frappe/utils/nestedset.py 查看文件

@@ -237,6 +237,28 @@ def validate_loop(doctype, name, lft, rgt):
frappe.throw(_("Item cannot be added to its own descendents"), NestedSetRecursionError)


def remove_subtree(doctype: str, name: str, throw=True):
"""Remove doc and all its children."""
frappe.has_permission(doctype, ptype="delete", throw=throw)

# Determine the `lft` and `rgt` of the subtree to be removed.
lft, rgt = frappe.db.get_value(doctype, name, ["lft", "rgt"])

# Delete the subtree by removing all nodes whose values for `lft` and `rgt`
# lie within above values or match them.
frappe.db.delete(doctype, {"lft": (">=", lft), "rgt": ("<=", rgt)})

# The width of the subtree is calculated as the difference between `rgt` and
# `lft` plus 1.
width = rgt - lft + 1

# All `lft` and `rgt` values, that are greater than the `rgt` of the removed
# subtree, must be reduced by the width of the subtree.
table = frappe.qb.DocType(doctype)
frappe.qb.update(table).set(table.lft, table.lft - width).where(table.lft > rgt).run()
frappe.qb.update(table).set(table.rgt, table.rgt - width).where(table.rgt > rgt).run()


class NestedSet(Document):
def __setup__(self):
if self.meta.get("nsm_parent_field"):


正在加载...
取消
保存