mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Recursive delete fix fix (#5819)
* Enable mysql checks as part of PR * Add debug for CI * Add delete_nodes method - Ensure that the "parent" field is set to None before delete - This means that we do not violate any ForeignKey constraints due to undefined order of operations
This commit is contained in:
parent
4913acda79
commit
2908ad0721
1
.github/workflows/qc_checks.yaml
vendored
1
.github/workflows/qc_checks.yaml
vendored
@ -274,7 +274,6 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
needs: [ 'pep_style', 'pre-commit' ]
|
||||
if: github.event_name == 'push'
|
||||
|
||||
env:
|
||||
# Database backend configuration
|
||||
|
@ -660,12 +660,14 @@ class InvenTreeTree(MPTTModel):
|
||||
D) delete_children = False and delete_items = False
|
||||
"""
|
||||
|
||||
child_nodes = self.get_descendants(include_self=False)
|
||||
|
||||
# Case A: Delete all child items, and all child nodes.
|
||||
# - Delete all items at any lower level
|
||||
# - Delete all descendant nodes
|
||||
if delete_children and delete_items:
|
||||
self.get_items(cascade=True).delete()
|
||||
self.get_descendants(include_self=False).delete()
|
||||
self.delete_nodes(child_nodes)
|
||||
|
||||
# Case B: Delete all child nodes, but move all child items up to the parent
|
||||
# - Move all items at any lower level to the parent of this item
|
||||
@ -674,7 +676,8 @@ class InvenTreeTree(MPTTModel):
|
||||
self.get_items(cascade=True).update(**{
|
||||
self.ITEM_PARENT_KEY: self.parent
|
||||
})
|
||||
self.get_descendants(include_self=False).delete()
|
||||
|
||||
self.delete_nodes(child_nodes)
|
||||
|
||||
# Case C: Delete all child items, but keep all child nodes
|
||||
# - Remove all items directly associated with this node
|
||||
@ -692,6 +695,21 @@ class InvenTreeTree(MPTTModel):
|
||||
})
|
||||
self.get_children().update(parent=self.parent)
|
||||
|
||||
def delete_nodes(self, nodes):
|
||||
"""Delete a set of nodes from the tree.
|
||||
|
||||
1. First, set the "parent" value for selected nodes to None
|
||||
2. Then, perform bulk deletion of selected nodes
|
||||
|
||||
Step 1. is required because we cannot guarantee the order-of-operations in the db backend
|
||||
|
||||
Arguments:
|
||||
nodes: A queryset of nodes to delete
|
||||
"""
|
||||
|
||||
nodes.update(parent=None)
|
||||
nodes.delete()
|
||||
|
||||
def validate_unique(self, exclude=None):
|
||||
"""Validate that this tree instance satisfies our uniqueness requirements.
|
||||
|
||||
|
@ -226,6 +226,8 @@ class CategoryTest(TestCase):
|
||||
# Clear out any existing parts
|
||||
Part.objects.all().delete()
|
||||
|
||||
PartCategory.objects.rebuild()
|
||||
|
||||
# First, create a structured tree of part categories
|
||||
A = PartCategory.objects.create(
|
||||
name='A',
|
||||
|
Loading…
Reference in New Issue
Block a user