def delete(self): from treemenus.utils import clean_ranks old_parent = self.parent super(MenuItem, self).delete() if old_parent: clean_ranks(old_parent.children())
def move_item_or_clean_ranks(menu_item, vector): ''' Helper function to move and item up or down in the database. If the moving fails, we assume that the ranks were corrupted, so we clean them and try the moving again. ''' try: move_item(menu_item, vector) except MenuItem.DoesNotExist: if menu_item.parent: clean_ranks(menu_item.parent.children()) fresh_menu_item = MenuItem.objects.get(pk=menu_item.pk) move_item(fresh_menu_item, vector)
def save(self, force_insert=False, force_update=False): from treemenus.utils import clean_ranks # Calculate level old_level = self.level if self.parent: self.level = self.parent.level + 1 else: self.level = 0 if self.pk: new_parent = self.parent old_parent = MenuItem.objects.get(pk=self.pk).parent if old_parent != new_parent: #If so, we need to recalculate the new ranks for the item and its siblings (both old and new ones). if new_parent: clean_ranks( new_parent.children()) # Clean ranks for new siblings self.rank = new_parent.children().count() super(MenuItem, self).save( force_insert, force_update ) # Save menu item in DB. It has now officially changed parent. if old_parent: clean_ranks( old_parent.children()) # Clean ranks for old siblings else: super(MenuItem, self).save(force_insert, force_update) # Save menu item in DB else: # Saving the menu item for the first time (i.e creating the object) if not self.has_siblings(): # No siblings - initial rank is 0. self.rank = 0 else: # Has siblings - initial rank is highest sibling rank plus 1. siblings = self.siblings().order_by('-rank') self.rank = siblings[0].rank + 1 super(MenuItem, self).save(force_insert, force_update) # If level has changed, force children to refresh their own level if old_level != self.level: for child in self.children(): child.save( ) # Just saving is enough, it'll refresh its level correctly.
def save(self, force_insert=False, **kwargs): from treemenus.utils import clean_ranks # Calculate level old_level = self.level if self.parent: self.level = self.parent.level + 1 else: self.level = 0 if self.pk: new_parent = self.parent old_parent = MenuItem.objects.get(pk=self.pk).parent if old_parent != new_parent: # If so, we need to recalculate the new ranks for the item # and its siblings (both old and new ones). if new_parent: # Clean ranks for new siblings clean_ranks(new_parent.children()) self.rank = new_parent.children().count() # Save menu item in DB. It has now officially changed parent. super(MenuItem, self).save(force_insert, **kwargs) if old_parent: # Clean ranks for old siblings clean_ranks(old_parent.children()) else: # Save menu item in DB super(MenuItem, self).save(force_insert, **kwargs) else: # Saving the menu item for the first time (i.e creating the object) if not self.has_siblings(): # No siblings - initial rank is 0. self.rank = 0 else: # Has siblings - initial rank is highest sibling rank plus 1. siblings = self.siblings().order_by('-rank') self.rank = siblings[0].rank + 1 super(MenuItem, self).save(force_insert, **kwargs) # If level has changed, force children to refresh their own level if old_level != self.level: for child in self.children(): # Just saving is enough, it'll refresh its level correctly. child.save()
def test_clean_children_ranks(self): menu = Menu(name='menu_clean_children_ranks') menu.save() menu_item1 = MenuItem.objects.create(caption='menu_item1', parent=menu.root_item) menu_item2 = MenuItem.objects.create(caption='menu_item2', parent=menu.root_item) menu_item3 = MenuItem.objects.create(caption='menu_item3', parent=menu.root_item) menu_item4 = MenuItem.objects.create(caption='menu_item4', parent=menu.root_item) # Initial check self.assertEquals(menu_item1.rank, 0) self.assertEquals(menu_item2.rank, 1) self.assertEquals(menu_item3.rank, 2) self.assertEquals(menu_item4.rank, 3) # Mess up ranks menu_item1.rank = 99 menu_item1.save() menu_item2.rank = -150 menu_item2.save() menu_item3.rank = 3 menu_item3.save() menu_item4.rank = 67 menu_item4.save() clean_ranks(menu.root_item.children()) # Retrieve objects from db menu_item1 = MenuItem.objects.get(caption='menu_item1', parent=menu.root_item) menu_item2 = MenuItem.objects.get(caption='menu_item2', parent=menu.root_item) menu_item3 = MenuItem.objects.get(caption='menu_item3', parent=menu.root_item) menu_item4 = MenuItem.objects.get(caption='menu_item4', parent=menu.root_item) self.assertEquals(menu_item1.rank, 3) self.assertEquals(menu_item2.rank, 0) self.assertEquals(menu_item3.rank, 1) self.assertEquals(menu_item4.rank, 2)