2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-05 13:10:57 +00:00

Add option to recursively delete part categories (#3435)

* Add option to recursively delete part categories

Fixes #3384

* - Added test (broken ATM)
- Refactored parameters to booleanish

* Fix styling issues reported by flake8

* Working on unit testing

* Added on_commit debugging callback

* Separate the recursive part of the deletion into another method
to make sure that the delete operation is performed in a single transaction

* Trying transactions with @transactions.atomic

* Fix flake8 reported issues

* Removed unused debug callback

* Fixed tests for category recursive deletion

* Fix flake reported issues

* Fix flake reported issues
Again

* Remove unrelated formatting changes

* Fixed a part of review comments
This commit is contained in:
Miklós Márton
2022-11-08 01:57:00 +01:00
committed by GitHub
parent adcb975853
commit f6cfc12343
6 changed files with 218 additions and 26 deletions

View File

@ -63,31 +63,46 @@ class PartCategory(MetadataMixin, InvenTreeTree):
default_keywords: Default keywords for parts created in this category
"""
def delete_recursive(self, *args, **kwargs):
"""This function handles the recursive deletion of subcategories depending on kwargs contents"""
delete_parts = kwargs.get('delete_parts', False)
parent_category = kwargs.get('parent_category', None)
if parent_category is None:
# First iteration, (no part_category kwargs passed)
parent_category = self.parent
for child_part in self.parts.all():
if delete_parts:
child_part.delete()
else:
child_part.category = parent_category
child_part.save()
for child_category in self.children.all():
if kwargs.get('delete_child_categories', False):
child_category.delete_recursive(**dict(delete_child_categories=True,
delete_parts=delete_parts,
parent_category=parent_category))
else:
child_category.parent = parent_category
child_category.save()
super().delete(*args, **dict())
def delete(self, *args, **kwargs):
"""Custom model deletion routine, which updates any child categories or parts.
This must be handled within a transaction.atomic(), otherwise the tree structure is damaged
"""
with transaction.atomic():
self.delete_recursive(**dict(delete_parts=kwargs.get('delete_parts', False),
delete_child_categories=kwargs.get('delete_child_categories', False),
parent_category=self.parent))
parent = self.parent
tree_id = self.tree_id
# Update each part in this category to point to the parent category
for p in self.parts.all():
p.category = self.parent
p.save()
# Update each child category
for child in self.children.all():
child.parent = self.parent
child.save()
super().delete(*args, **kwargs)
if parent is not None:
if self.parent is not None:
# Partially rebuild the tree (cheaper than a complete rebuild)
PartCategory.objects.partial_rebuild(tree_id)
PartCategory.objects.partial_rebuild(self.tree_id)
else:
PartCategory.objects.rebuild()